diff --git a/Libraries/LibHTML/CSS/StyleProperties.h b/Libraries/LibHTML/CSS/StyleProperties.h index 0493d29d4d..cb4771fe72 100644 --- a/Libraries/LibHTML/CSS/StyleProperties.h +++ b/Libraries/LibHTML/CSS/StyleProperties.h @@ -6,8 +6,10 @@ class Color; -class StyleProperties { +class StyleProperties : public RefCounted { public: + static NonnullRefPtr create() { return adopt(*new StyleProperties); } + template inline void for_each_property(Callback callback) const { diff --git a/Libraries/LibHTML/CSS/StyleResolver.cpp b/Libraries/LibHTML/CSS/StyleResolver.cpp index 17ef4b5a4d..4a58de33e2 100644 --- a/Libraries/LibHTML/CSS/StyleResolver.cpp +++ b/Libraries/LibHTML/CSS/StyleResolver.cpp @@ -57,22 +57,22 @@ NonnullRefPtrVector StyleResolver::collect_matching_rules(const Eleme return matching_rules; } -StyleProperties StyleResolver::resolve_style(const Element& element, const StyleProperties* parent_properties) const +NonnullRefPtr StyleResolver::resolve_style(const Element& element, const StyleProperties* parent_properties) const { - StyleProperties style_properties; + auto style_properties = StyleProperties::create(); if (parent_properties) { parent_properties->for_each_property([&](const StringView& name, auto& value) { // TODO: proper inheritance if (name.starts_with("font") || name == "white-space" || name == "color" || name == "text-decoration") - style_properties.set_property(name, value); + style_properties->set_property(name, value); }); } auto matching_rules = collect_matching_rules(element); for (auto& rule : matching_rules) { for (auto& property : rule.declaration().properties()) { - style_properties.set_property(property.name, property.value); + style_properties->set_property(property.name, property.value); } } @@ -80,7 +80,7 @@ StyleProperties StyleResolver::resolve_style(const Element& element, const Style if (!style_attribute.is_null()) { if (auto declaration = parse_css_declaration(style_attribute)) { for (auto& property : declaration->properties()) { - style_properties.set_property(property.name, property.value); + style_properties->set_property(property.name, property.value); } } } diff --git a/Libraries/LibHTML/CSS/StyleResolver.h b/Libraries/LibHTML/CSS/StyleResolver.h index 9f814ace07..077e0545e2 100644 --- a/Libraries/LibHTML/CSS/StyleResolver.h +++ b/Libraries/LibHTML/CSS/StyleResolver.h @@ -18,7 +18,7 @@ public: Document& document() { return m_document; } const Document& document() const { return m_document; } - StyleProperties resolve_style(const Element&, const StyleProperties* parent_properties) const; + NonnullRefPtr resolve_style(const Element&, const StyleProperties* parent_properties) const; NonnullRefPtrVector collect_matching_rules(const Element&) const; diff --git a/Libraries/LibHTML/DOM/Node.cpp b/Libraries/LibHTML/DOM/Node.cpp index 2e81d3de3d..141985f026 100644 --- a/Libraries/LibHTML/DOM/Node.cpp +++ b/Libraries/LibHTML/DOM/Node.cpp @@ -22,19 +22,16 @@ Node::~Node() RefPtr Node::create_layout_node(const StyleResolver& resolver, const StyleProperties* parent_properties) const { if (is_document()) - return adopt(*new LayoutDocument(static_cast(*this), {})); - - StyleProperties style_properties; - if (is_element()) - style_properties = resolver.resolve_style(static_cast(*this), parent_properties); - else - style_properties = *parent_properties; - - auto display_property = style_properties.property("display"); - String display = display_property.has_value() ? display_property.release_value()->to_string() : "inline"; + return adopt(*new LayoutDocument(static_cast(*this), StyleProperties::create())); if (is_text()) - return adopt(*new LayoutText(static_cast(*this), move(style_properties))); + return adopt(*new LayoutText(static_cast(*this))); + + auto style_properties = resolver.resolve_style(static_cast(*this), parent_properties); + + auto display_property = style_properties->property("display"); + String display = display_property.has_value() ? display_property.release_value()->to_string() : "inline"; + if (display == "none") return nullptr; if (display == "block" || display == "list-item") @@ -71,7 +68,7 @@ RefPtr Node::create_layout_tree(const StyleResolver& resolver, const for (auto layout_child : layout_children) if (have_block_children && have_inline_children && !layout_child->is_block()) { - if (layout_child->is_text() && static_cast(*layout_child).text() == " ") + if (layout_child->is_text() && static_cast(*layout_child).text_for_style(*parent_properties) == " ") continue; layout_node->inline_wrapper().append_child(*layout_child); } else { diff --git a/Libraries/LibHTML/Layout/LayoutBlock.cpp b/Libraries/LibHTML/Layout/LayoutBlock.cpp index 04f6ad80bc..d2851879d6 100644 --- a/Libraries/LibHTML/Layout/LayoutBlock.cpp +++ b/Libraries/LibHTML/Layout/LayoutBlock.cpp @@ -3,7 +3,7 @@ #include #include -LayoutBlock::LayoutBlock(const Node* node, StyleProperties&& style_properties) +LayoutBlock::LayoutBlock(const Node* node, NonnullRefPtr style_properties) : LayoutNode(node, move(style_properties)) { } @@ -15,7 +15,7 @@ LayoutBlock::~LayoutBlock() LayoutNode& LayoutBlock::inline_wrapper() { if (!last_child() || !last_child()->is_block() || last_child()->node() != nullptr) { - append_child(adopt(*new LayoutBlock(nullptr, {}))); + append_child(adopt(*new LayoutBlock(nullptr, style_properties()))); } return *last_child(); } diff --git a/Libraries/LibHTML/Layout/LayoutBlock.h b/Libraries/LibHTML/Layout/LayoutBlock.h index 093f0adb6f..ee1989d9cb 100644 --- a/Libraries/LibHTML/Layout/LayoutBlock.h +++ b/Libraries/LibHTML/Layout/LayoutBlock.h @@ -7,7 +7,7 @@ class Element; class LayoutBlock : public LayoutNode { public: - LayoutBlock(const Node*, StyleProperties&&); + LayoutBlock(const Node*, NonnullRefPtr); virtual ~LayoutBlock() override; virtual const char* class_name() const override { return "LayoutBlock"; } diff --git a/Libraries/LibHTML/Layout/LayoutDocument.cpp b/Libraries/LibHTML/Layout/LayoutDocument.cpp index 7f3717ce67..4f1d3fd45e 100644 --- a/Libraries/LibHTML/Layout/LayoutDocument.cpp +++ b/Libraries/LibHTML/Layout/LayoutDocument.cpp @@ -1,6 +1,6 @@ #include -LayoutDocument::LayoutDocument(const Document& document, StyleProperties&& style_properties) +LayoutDocument::LayoutDocument(const Document& document, NonnullRefPtr style_properties) : LayoutBlock(&document, move(style_properties)) { } diff --git a/Libraries/LibHTML/Layout/LayoutDocument.h b/Libraries/LibHTML/Layout/LayoutDocument.h index 88acbb8e69..ec1ce9d276 100644 --- a/Libraries/LibHTML/Layout/LayoutDocument.h +++ b/Libraries/LibHTML/Layout/LayoutDocument.h @@ -5,7 +5,7 @@ class LayoutDocument final : public LayoutBlock { public: - LayoutDocument(const Document&, StyleProperties&&); + explicit LayoutDocument(const Document&, NonnullRefPtr); virtual ~LayoutDocument() override; const Document& node() const { return static_cast(*LayoutNode::node()); } diff --git a/Libraries/LibHTML/Layout/LayoutInline.cpp b/Libraries/LibHTML/Layout/LayoutInline.cpp index 6b403df5cf..345bfbdef6 100644 --- a/Libraries/LibHTML/Layout/LayoutInline.cpp +++ b/Libraries/LibHTML/Layout/LayoutInline.cpp @@ -1,7 +1,7 @@ #include #include -LayoutInline::LayoutInline(const Node& node, StyleProperties&& style_properties) +LayoutInline::LayoutInline(const Node& node, RefPtr style_properties) : LayoutNode(&node, move(style_properties)) { } diff --git a/Libraries/LibHTML/Layout/LayoutInline.h b/Libraries/LibHTML/Layout/LayoutInline.h index eb387c04bf..34dfba49d6 100644 --- a/Libraries/LibHTML/Layout/LayoutInline.h +++ b/Libraries/LibHTML/Layout/LayoutInline.h @@ -6,7 +6,7 @@ class LayoutBlock; class LayoutInline : public LayoutNode { public: - LayoutInline(const Node&, StyleProperties&&); + LayoutInline(const Node&, RefPtr); virtual ~LayoutInline() override; virtual const char* class_name() const override { return "LayoutInline"; } diff --git a/Libraries/LibHTML/Layout/LayoutNode.cpp b/Libraries/LibHTML/Layout/LayoutNode.cpp index e73c791901..f3b8946b3a 100644 --- a/Libraries/LibHTML/Layout/LayoutNode.cpp +++ b/Libraries/LibHTML/Layout/LayoutNode.cpp @@ -7,9 +7,9 @@ //#define DRAW_BOXES_AROUND_LAYOUT_NODES //#define DRAW_BOXES_AROUND_HOVERED_NODES -LayoutNode::LayoutNode(const Node* node, StyleProperties&& style_properties) +LayoutNode::LayoutNode(const Node* node, RefPtr style_properties) : m_node(node) - , m_style_properties(style_properties) + , m_style_properties(move(style_properties)) { } diff --git a/Libraries/LibHTML/Layout/LayoutNode.h b/Libraries/LibHTML/Layout/LayoutNode.h index ed31dd424d..b02acd2a92 100644 --- a/Libraries/LibHTML/Layout/LayoutNode.h +++ b/Libraries/LibHTML/Layout/LayoutNode.h @@ -62,18 +62,23 @@ public: virtual LayoutNode& inline_wrapper() { return *this; } - const StyleProperties& style_properties() const { return m_style_properties; } + const StyleProperties& style_properties() const + { + if (m_style_properties) + return *m_style_properties; + return parent()->style_properties(); + } void inserted_into(LayoutNode&) {} void removed_from(LayoutNode&) {} protected: - explicit LayoutNode(const Node*, StyleProperties&&); + explicit LayoutNode(const Node*, RefPtr); private: const Node* m_node { nullptr }; - StyleProperties m_style_properties; + RefPtr m_style_properties; ComputedStyle m_style; Rect m_rect; }; diff --git a/Libraries/LibHTML/Layout/LayoutText.cpp b/Libraries/LibHTML/Layout/LayoutText.cpp index 663a3e10b1..bb2a68eb2a 100644 --- a/Libraries/LibHTML/Layout/LayoutText.cpp +++ b/Libraries/LibHTML/Layout/LayoutText.cpp @@ -7,8 +7,8 @@ #include #include -LayoutText::LayoutText(const Text& text, StyleProperties&& style_properties) - : LayoutInline(text, move(style_properties)) +LayoutText::LayoutText(const Text& text) + : LayoutInline(text, {}) { } @@ -78,12 +78,13 @@ static bool is_all_whitespace(const String& string) return true; } -const String& LayoutText::text() const +const String& LayoutText::text_for_style(const StyleProperties& style_properties) const { static String one_space = " "; - if (is_all_whitespace(node().data())) - if (style_properties().string_or_fallback("white-space", "normal") == "normal") + if (is_all_whitespace(node().data())) { + if (style_properties.string_or_fallback("white-space", "normal") == "normal") return one_space; + } return node().data(); } diff --git a/Libraries/LibHTML/Layout/LayoutText.h b/Libraries/LibHTML/Layout/LayoutText.h index 5d89f6e3a1..594cfbeee3 100644 --- a/Libraries/LibHTML/Layout/LayoutText.h +++ b/Libraries/LibHTML/Layout/LayoutText.h @@ -8,12 +8,12 @@ class LineBoxFragment; class LayoutText : public LayoutInline { public: - LayoutText(const Text&, StyleProperties&&); + explicit LayoutText(const Text&); virtual ~LayoutText() override; const Text& node() const { return static_cast(*LayoutNode::node()); } - const String& text() const; + const String& text_for_style(const StyleProperties&) const; virtual const char* class_name() const override { return "LayoutText"; } virtual bool is_text() const final { return true; } @@ -22,6 +22,8 @@ public: virtual void split_into_lines(LayoutBlock& container) override; + const StyleProperties& style_properties() const { return parent()->style_properties(); } + private: template void for_each_word(Callback) const; @@ -29,7 +31,6 @@ private: void for_each_source_line(Callback) const; void load_font(); - void compute_runs(); RefPtr m_font; };