diff --git a/LibHTML/CSS/StyleResolver.cpp b/LibHTML/CSS/StyleResolver.cpp index 15aef1ba51..47c28e8580 100644 --- a/LibHTML/CSS/StyleResolver.cpp +++ b/LibHTML/CSS/StyleResolver.cpp @@ -1,5 +1,7 @@ #include #include +#include +#include #include #include #include @@ -51,15 +53,19 @@ NonnullRefPtrVector StyleResolver::collect_matching_rules(const Eleme return matching_rules; } -OwnPtr StyleResolver::resolve_document_style(const Document& document) +NonnullRefPtr StyleResolver::create_styled_node(const Document& document) { - UNUSED_PARAM(document); - return make(); + return StyledNode::create(document); } -OwnPtr StyleResolver::resolve_element_style(const Element& element) +NonnullRefPtr StyleResolver::create_styled_node(const Element& element) { - auto style = make(); + auto style = StyledNode::create(element); auto matching_rules = collect_matching_rules(element); + for (auto& rule : matching_rules) { + for (auto& declaration : rule.declarations()) { + style->set_property(declaration.property_name(), declaration.value()); + } + } return style; } diff --git a/LibHTML/CSS/StyleResolver.h b/LibHTML/CSS/StyleResolver.h index a11133e0f9..eec7042b29 100644 --- a/LibHTML/CSS/StyleResolver.h +++ b/LibHTML/CSS/StyleResolver.h @@ -2,12 +2,13 @@ #include #include -#include class Document; class Element; +class ParentNode; class StyleRule; class StyleSheet; +class StyledNode; class StyleResolver { public: @@ -19,8 +20,8 @@ public: void add_sheet(const StyleSheet& sheet) { m_sheets.append(sheet); } - OwnPtr resolve_element_style(const Element&); - OwnPtr resolve_document_style(const Document&); + NonnullRefPtr create_styled_node(const Element&); + NonnullRefPtr create_styled_node(const Document&); NonnullRefPtrVector collect_matching_rules(const Element&) const; diff --git a/LibHTML/CSS/StyledNode.h b/LibHTML/CSS/StyledNode.h index eaf171e570..61d43b5156 100644 --- a/LibHTML/CSS/StyledNode.h +++ b/LibHTML/CSS/StyledNode.h @@ -10,6 +10,10 @@ class Node; class StyledNode : public TreeNode { public: + static NonnullRefPtr create(const Node& node) + { + return adopt(*new StyledNode(&node)); + } ~StyledNode(); const Node* node() const { return m_node; } @@ -28,6 +32,18 @@ public: callback(*node); } + template + inline void for_each_property(Callback callback) const + { + for (auto& it : m_property_values) + callback(it.key, *it.value); + } + + void set_property(const String& name, NonnullRefPtr value) + { + m_property_values.set(name, move(value)); + } + protected: explicit StyledNode(const Node*); diff --git a/LibHTML/Dump.cpp b/LibHTML/Dump.cpp index 4d9632509f..477b8aa55a 100644 --- a/LibHTML/Dump.cpp +++ b/LibHTML/Dump.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -67,6 +68,38 @@ void dump_tree(const LayoutNode& layout_node) --indent; } +void dump_tree(const StyledNode& styled_node) +{ + static int indent = 0; + for (int i = 0; i < indent; ++i) + printf(" "); + + String tag_name; + auto& node = *styled_node.node(); + if (node.is_text()) + tag_name = "#text"; + else if (node.is_document()) + tag_name = "#document"; + else if (node.is_element()) + tag_name = static_cast(node).tag_name(); + else + tag_name = "???"; + + printf("%s", tag_name.characters()); + printf("\n"); + + styled_node.for_each_property([&](auto& key, auto& value) { + for (int i = 0; i < indent; ++i) + printf(" "); + printf(" (%s: %s)\n", key.characters(), value.to_string().characters()); + }); + ++indent; + styled_node.for_each_child([](auto& child) { + dump_tree(child); + }); + --indent; +} + void dump_rule(const StyleRule& rule) { printf("Rule:\n"); diff --git a/LibHTML/Dump.h b/LibHTML/Dump.h index 546e556ba7..c7c0953e6d 100644 --- a/LibHTML/Dump.h +++ b/LibHTML/Dump.h @@ -4,8 +4,10 @@ class Node; class LayoutNode; class StyleRule; class StyleSheet; +class StyledNode; void dump_tree(const Node&); +void dump_tree(const StyledNode&); void dump_tree(const LayoutNode&); void dump_sheet(const StyleSheet&); void dump_rule(const StyleRule&); diff --git a/LibHTML/test.cpp b/LibHTML/test.cpp index 07eed25dc1..e3d23837d8 100644 --- a/LibHTML/test.cpp +++ b/LibHTML/test.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -28,18 +29,29 @@ int main(int argc, char** argv) StyleResolver resolver(*doc); resolver.add_sheet(*sheet); - auto doc_style = resolver.resolve_document_style(*doc); - - Function resolve_style = [&](const ParentNode& node) { - node.for_each_child([&](const Node& child) { + Function(const Node&, StyledNode*)> resolve_style = [&](const Node& node, StyledNode* parent_styled_node) -> RefPtr { + auto styled_node = [&]() -> RefPtr { + if (node.is_element()) + return resolver.create_styled_node(static_cast(node)); + if (node.is_document()) + return resolver.create_styled_node(static_cast(node)); + return nullptr; + }(); + if (!styled_node) + return nullptr; + if (parent_styled_node) + parent_styled_node->append_child(*styled_node); + static_cast(node).for_each_child([&](const Node& child) { if (!child.is_element()) return; - auto style = resolver.resolve_element_style(static_cast(node)); - printf("Resolved LayoutStyle{%p} for Element{%p}\n", style.ptr(), &node); - resolve_style(static_cast(child)); + auto styled_child_node = resolve_style(static_cast(child), styled_node.ptr()); + printf("Created StyledNode{%p} for Element{%p}\n", styled_child_node.ptr(), &node); }); + return styled_node; }; - resolve_style(*doc); + auto styled_root = resolve_style(*doc, nullptr); + + dump_tree(*styled_root); doc->build_layout_tree(); ASSERT(doc->layout_node());