srctree

Robin Linden parent d31d5f36 5a711689
style: Switch the dom::Node to being a regular reference

Things have shifted enough that StyledNode doesn't need to be copyableor moveable anymore.

inlinesplit
browser/gui/app.cpp added: 66, removed: 67, total 0
@@ -245,7 +245,7 @@ dom::Node const *App::get_hovered_node(geom::Position p) const {
return nullptr;
}
 
return &moused_over->node->node.get();
return &moused_over->node->node;
}
 
std::string App::get_hovered_element_text(geom::Position p) const {
 
layout/layout.cpp added: 66, removed: 67, total 0
@@ -66,7 +66,7 @@ std::optional<LayoutBox> create_tree(style::StyledNode const &node) {
return LayoutBox{&node, LayoutType::Inline};
},
},
node.node.get());
node.node);
}
 
// TODO(robinlinden):
@@ -87,9 +87,9 @@ int to_px(std::string_view property, int const font_size) {
void calculate_width(LayoutBox &box, geom::Rect const &parent, int const font_size) {
assert(box.node != nullptr);
 
if (std::holds_alternative<dom::Text>(box.node->node.get())) {
if (std::holds_alternative<dom::Text>(box.node->node)) {
// TODO(robinlinden): Measure the text for real.
auto text_node = std::get<dom::Text>(box.node->node.get());
auto text_node = std::get<dom::Text>(box.node->node);
box.dimensions.content.width = std::min(parent.width, static_cast<int>(text_node.text.size()) * font_size / 2);
return;
}
@@ -117,7 +117,7 @@ void calculate_position(LayoutBox &box, geom::Rect const &parent) {
 
void calculate_height(LayoutBox &box, int const font_size) {
assert(box.node != nullptr);
if (std::holds_alternative<dom::Text>(box.node->node.get())) {
if (std::holds_alternative<dom::Text>(box.node->node)) {
box.dimensions.content.height = font_size;
}
 
@@ -254,7 +254,7 @@ void print_box(LayoutBox const &box, std::ostream &os, uint8_t depth = 0) {
}
 
if (box.node != nullptr) {
os << to_str(box.node->node.get()) << '\n';
os << to_str(box.node->node) << '\n';
for (int8_t i = 0; i < depth; ++i) {
os << " ";
}
 
layout/layout_test.cpp added: 66, removed: 67, total 0
@@ -554,27 +554,29 @@ int main() {
 
etest::test("em sizes depend on the font-size", [] {
auto dom_root = dom::create_element_node("html", {}, {});
auto style_root = style::StyledNode{
.node = dom_root,
.properties = {
std::pair{"font-size", "10px"},
std::pair{"height", "10em"},
std::pair{"width", "10em"},
},
.children = {},
};
{
auto style_root = style::StyledNode{
.node = dom_root,
.properties = {
std::pair{"font-size", "10px"},
std::pair{"height", "10em"},
std::pair{"width", "10em"},
},
.children = {},
};
 
auto expected_layout = layout::LayoutBox{
.node = &style_root,
.type = LayoutType::Block,
.dimensions = {{0, 0, 100, 100}},
.children = {}
};
auto expected_layout = layout::LayoutBox{
.node = &style_root,
.type = LayoutType::Block,
.dimensions = {{0, 0, 100, 100}},
.children = {}
};
 
expect(layout::create_layout(style_root, 1000) == expected_layout);
expect(layout::create_layout(style_root, 1000) == expected_layout);
}
 
// Doubling the font-size should double the width/height.
style_root = style::StyledNode{
auto style_root = style::StyledNode{
.node = dom_root,
.properties = {
std::pair{"font-size", "20px"},
@@ -584,7 +586,7 @@ int main() {
.children = {},
};
 
expected_layout = layout::LayoutBox{
auto expected_layout = layout::LayoutBox{
.node = &style_root,
.type = LayoutType::Block,
.dimensions = {{0, 0, 200, 200}},
@@ -596,27 +598,29 @@ int main() {
 
etest::test("px sizes don't depend on the font-size", [] {
auto dom_root = dom::create_element_node("html", {}, {});
auto style_root = style::StyledNode{
.node = dom_root,
.properties = {
std::pair{"font-size", "10px"},
std::pair{"height", "10px"},
std::pair{"width", "10px"},
},
.children = {},
};
{
auto style_root = style::StyledNode{
.node = dom_root,
.properties = {
std::pair{"font-size", "10px"},
std::pair{"height", "10px"},
std::pair{"width", "10px"},
},
.children = {},
};
 
auto expected_layout = layout::LayoutBox{
.node = &style_root,
.type = LayoutType::Block,
.dimensions = {{0, 0, 10, 10}},
.children = {}
};
auto expected_layout = layout::LayoutBox{
.node = &style_root,
.type = LayoutType::Block,
.dimensions = {{0, 0, 10, 10}},
.children = {}
};
 
expect(layout::create_layout(style_root, 1000) == expected_layout);
expect(layout::create_layout(style_root, 1000) == expected_layout);
}
 
// Doubling the font-size shouldn't change the width/height.
style_root = style::StyledNode{
auto style_root = style::StyledNode{
.node = dom_root,
.properties = {
std::pair{"font-size", "20px"},
@@ -626,7 +630,7 @@ int main() {
.children = {},
};
 
expected_layout = layout::LayoutBox{
auto expected_layout = layout::LayoutBox{
.node = &style_root,
.type = LayoutType::Block,
.dimensions = {{0, 0, 10, 10}},
 
render/render.cpp added: 66, removed: 67, total 0
@@ -61,7 +61,7 @@ bool looks_like_hex(std::string_view str) {
}
 
dom::Text const *try_get_text(layout::LayoutBox const &layout) {
return std::get_if<dom::Text>(&layout.node->node.get());
return std::get_if<dom::Text>(&layout.node->node);
}
 
gfx::Color from_hex_chars(std::string_view hex_chars) {
 
style/style.cpp added: 66, removed: 67, total 0
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2021 Robin Lindén <dev@robinlinden.eu>
// SPDX-FileCopyrightText: 2021-2022 Robin Lindén <dev@robinlinden.eu>
//
// SPDX-License-Identifier: BSD-2-Clause
 
@@ -45,17 +45,17 @@ std::vector<std::pair<std::string, std::string>> matching_rules(
}
 
namespace {
StyledNode style_tree_impl(std::reference_wrapper<dom::Node const> root, std::vector<css::Rule> const &stylesheet) {
StyledNode style_tree_impl(dom::Node const &root, std::vector<css::Rule> const &stylesheet) {
std::vector<StyledNode> children{};
 
if (auto const *element = std::get_if<dom::Element>(&root.get())) {
if (auto const *element = std::get_if<dom::Element>(&root)) {
for (auto const &child : element->children) {
children.push_back(style_tree_impl(child, stylesheet));
}
}
 
auto properties = std::holds_alternative<dom::Element>(root.get())
? matching_rules(std::get<dom::Element>(root.get()), stylesheet)
auto properties = std::holds_alternative<dom::Element>(root)
? matching_rules(std::get<dom::Element>(root), stylesheet)
: std::vector<std::pair<std::string, std::string>>{};
 
return {
@@ -66,8 +66,7 @@ StyledNode style_tree_impl(std::reference_wrapper<dom::Node const> root, std::ve
}
} // namespace
 
std::unique_ptr<StyledNode> style_tree(
std::reference_wrapper<dom::Node const> root, std::vector<css::Rule> const &stylesheet) {
std::unique_ptr<StyledNode> style_tree(dom::Node const &root, std::vector<css::Rule> const &stylesheet) {
return std::make_unique<StyledNode>(style_tree_impl(root, stylesheet));
}
 
 
style/style.h added: 66, removed: 67, total 0
@@ -9,7 +9,6 @@
#include "dom/dom.h"
#include "style/styled_node.h"
 
#include <functional>
#include <memory>
#include <string>
#include <string_view>
@@ -23,8 +22,7 @@ bool is_match(dom::Element const &element, std::string_view selector);
std::vector<std::pair<std::string, std::string>> matching_rules(
dom::Element const &element, std::vector<css::Rule> const &stylesheet);
 
std::unique_ptr<StyledNode> style_tree(
std::reference_wrapper<dom::Node const> root, std::vector<css::Rule> const &stylesheet);
std::unique_ptr<StyledNode> style_tree(dom::Node const &root, std::vector<css::Rule> const &stylesheet);
 
} // namespace style
 
 
style/styled_node.h added: 66, removed: 67, total 0
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2021 Robin Lindén <dev@robinlinden.eu>
// SPDX-FileCopyrightText: 2021-2022 Robin Lindén <dev@robinlinden.eu>
//
// SPDX-License-Identifier: BSD-2-Clause
 
@@ -7,7 +7,6 @@
 
#include "dom/dom.h"
 
#include <functional>
#include <optional>
#include <string>
#include <string_view>
@@ -16,15 +15,14 @@
 
namespace style {
 
// Using reference_wrapper here because I want this to be movable and copy-constructible.
struct StyledNode {
std::reference_wrapper<dom::Node const> node;
dom::Node const &node;
std::vector<std::pair<std::string, std::string>> properties;
std::vector<StyledNode> children;
};
 
[[nodiscard]] inline bool operator==(style::StyledNode const &a, style::StyledNode const &b) noexcept {
return a.node.get() == b.node.get() && a.properties == b.properties && a.children == b.children;
return a.node == b.node && a.properties == b.properties && a.children == b.children;
}
 
std::optional<std::string_view> get_property(StyledNode const &node, std::string_view property);
 
tui/tui.cpp added: 66, removed: 67, total 0
@@ -29,7 +29,7 @@ ftxui::Elements parse_children(layout::LayoutBox const &box) {
ftxui::Element element_from_node(layout::LayoutBox const &box) {
switch (box.type) {
case layout::LayoutType::Inline: {
if (auto text = std::get_if<dom::Text>(&box.node->node.get())) {
if (auto text = std::get_if<dom::Text>(&box.node->node)) {
return ftxui::paragraph(text->text);
}
return hbox(parse_children(box));