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;
};