srctree

Robin Linden parent c52b3cbd 0d9c3baa
style: Update property getters to use template arguments

This is to enforce passing the arguments at compile-time in order toswitch the return types to more reasonable types than strings.

inlinesplit
layout/layout.cpp added: 29, removed: 24, total 5
@@ -38,7 +38,7 @@ bool last_node_was_anonymous(LayoutBox const &box) {
std::optional<LayoutBox> create_tree(style::StyledNode const &node) {
auto visitor = util::Overloaded{
[&node](dom::Element const &) -> std::optional<LayoutBox> {
auto display = node.get_property(css::PropertyId::Display);
auto display = node.get_property<css::PropertyId::Display>();
if (display == "none") {
return std::nullopt;
}
 
layout/layout.h added: 29, removed: 24, total 5
@@ -47,7 +47,7 @@ std::optional<std::string_view> LayoutBox::get_property() const {
return std::nullopt;
}
 
return node->get_property(T);
return node->get_property<T>();
}
 
} // namespace layout
 
style/styled_node.cpp added: 29, removed: 24, total 5
@@ -71,9 +71,9 @@ std::map<css::PropertyId, std::string_view> const kInitialValues{
{css::PropertyId::MinWidth, "auto"sv},
};
 
std::string_view get_parent_property(style::StyledNode const &node, css::PropertyId property) {
std::string_view get_parent_raw_property(style::StyledNode const &node, css::PropertyId property) {
if (node.parent != nullptr) {
return node.parent->get_property(property);
return node.parent->get_raw_property(property);
}
 
return kInitialValues.at(property);
@@ -81,12 +81,12 @@ std::string_view get_parent_property(style::StyledNode const &node, css::Propert
 
} // namespace
 
std::string_view StyledNode::get_property(css::PropertyId property) const {
std::string_view StyledNode::get_raw_property(css::PropertyId property) const {
auto it = std::ranges::find_if(properties, [=](auto const &p) { return p.first == property; });
 
if (it == cend(properties)) {
if (is_inherited(property) && parent != nullptr) {
return parent->get_property(property);
return parent->get_raw_property(property);
}
 
return kInitialValues.at(property);
@@ -95,19 +95,19 @@ std::string_view StyledNode::get_property(css::PropertyId property) const {
return kInitialValues.at(property);
} else if (it->second == "inherit") {
// https://developer.mozilla.org/en-US/docs/Web/CSS/inherit
return get_parent_property(*this, property);
return get_parent_raw_property(*this, property);
} else if (it->second == "currentcolor") {
// https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#currentcolor_keyword
// If the "color" property has the value "currentcolor", treat it as "inherit".
if (it->first == css::PropertyId::Color) {
return get_parent_property(*this, property);
return get_parent_raw_property(*this, property);
}
 
// Even though we return the correct value here, if a property has
// "currentcolor" as its initial value, the caller have to manually look
// up the value of "color". This will be cleaned up along with the rest
// of the property management soon.
return get_property(css::PropertyId::Color);
return get_raw_property(css::PropertyId::Color);
}
 
return it->second;
 
style/styled_node.h added: 29, removed: 24, total 5
@@ -21,7 +21,12 @@ struct StyledNode {
std::vector<StyledNode> children;
StyledNode const *parent{nullptr};
 
std::string_view get_property(css::PropertyId) const;
std::string_view get_raw_property(css::PropertyId) const;
 
template<css::PropertyId T>
std::string_view get_property() const {
return get_raw_property(T);
}
};
 
[[nodiscard]] inline bool operator==(style::StyledNode const &a, style::StyledNode const &b) noexcept {
 
style/styled_node_test.cpp added: 29, removed: 24, total 5
@@ -20,7 +20,7 @@ int main() {
.children = {},
};
 
expect(styled_node.get_property(css::PropertyId::Width) == "15px"sv);
expect(styled_node.get_property<css::PropertyId::Width>() == "15px"sv);
});
 
etest::test("property inheritance", [] {
@@ -34,10 +34,10 @@ int main() {
auto &child = root.children.emplace_back(style::StyledNode{dom_node, {}, {}, &root});
 
// Not inherited, returns the initial value.
expect_eq(child.get_property(css::PropertyId::Width), "auto"sv);
expect_eq(child.get_property<css::PropertyId::Width>(), "auto"sv);
 
// Inherited, returns the parent's value.
expect_eq(child.get_property(css::PropertyId::FontSize), "15em"sv);
expect_eq(child.get_property<css::PropertyId::FontSize>(), "15em"sv);
});
 
etest::test("initial css keyword", [] {
@@ -56,7 +56,7 @@ int main() {
auto &child = root.children[0];
child.parent = &root;
 
expect_eq(child.get_property(css::PropertyId::Color), "canvastext"sv);
expect_eq(child.get_property<css::PropertyId::Color>(), "canvastext"sv);
});
 
etest::test("inherit css keyword", [] {
@@ -79,14 +79,14 @@ int main() {
child.parent = &root;
 
// inherit, but not in parent, so receives initial value for property.
expect_eq(child.get_property(css::PropertyId::Width), "auto"sv);
expect_eq(child.get_property<css::PropertyId::Width>(), "auto"sv);
 
// inherit, value in parent.
expect_eq(child.get_property(css::PropertyId::BackgroundColor), "blue"sv);
expect_eq(child.get_property<css::PropertyId::BackgroundColor>(), "blue"sv);
 
// inherit, no parent node.
child.parent = nullptr;
expect_eq(child.get_property(css::PropertyId::BackgroundColor), "transparent");
expect_eq(child.get_property<css::PropertyId::BackgroundColor>(), "transparent");
});
 
etest::test("currentcolor css keyword", [] {
@@ -107,11 +107,11 @@ int main() {
auto &child = root.children[0];
child.parent = &root;
 
expect_eq(child.get_property(css::PropertyId::BackgroundColor), "blue"sv);
expect_eq(child.get_property<css::PropertyId::BackgroundColor>(), "blue"sv);
 
// "color: currentcolor" should be treated as inherit.
child.properties.push_back({css::PropertyId::Color, "currentcolor"s});
expect_eq(child.get_property(css::PropertyId::Color), "blue"sv);
expect_eq(child.get_property<css::PropertyId::Color>(), "blue"sv);
});
 
return etest::run_all_tests();