summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-10-13 12:34:25 +0200
committerAndreas Kling <awesomekling@gmail.com>2019-10-13 12:43:31 +0200
commit49ac0c2e24ef00dae096c836a1429e03460a0cc7 (patch)
tree03b622a7f73e38f1589c94a1f43d84106296e345
parent48ef1d1bd1df6650a7406c7e747061c8de91915c (diff)
downloadserenity-49ac0c2e24ef00dae096c836a1429e03460a0cc7.zip
LibHTML: Move layout root from HtmlView to Document
The layout root is now kept alive via Document::m_layout_root. This will allow us to do more layout-related things inside the inner layer of LibHTML without reaching out to the HtmlView. I'd like to keep HtmlView at a slightly higher level, to prevent it from getting too complex. This patch also fixes accidental disconnection of the layout tree from the DOM after doing a layout tree rebuild. ~LayoutNode() now only unsets the DOM node's layout_node() if it's itself.
-rw-r--r--Applications/Browser/main.cpp1
-rw-r--r--Libraries/LibHTML/DOM/Document.cpp14
-rw-r--r--Libraries/LibHTML/DOM/Document.h7
-rw-r--r--Libraries/LibHTML/HtmlView.cpp43
-rw-r--r--Libraries/LibHTML/HtmlView.h4
-rw-r--r--Libraries/LibHTML/Layout/LayoutNode.cpp2
6 files changed, 51 insertions, 20 deletions
diff --git a/Applications/Browser/main.cpp b/Applications/Browser/main.cpp
index ec33614843..149dab1ff5 100644
--- a/Applications/Browser/main.cpp
+++ b/Applications/Browser/main.cpp
@@ -14,6 +14,7 @@
#include <LibHTML/Dump.h>
#include <LibHTML/HtmlView.h>
#include <LibHTML/Layout/LayoutBlock.h>
+#include <LibHTML/Layout/LayoutDocument.h>
#include <LibHTML/Layout/LayoutInline.h>
#include <LibHTML/Layout/LayoutNode.h>
#include <LibHTML/Parser/CSSParser.h>
diff --git a/Libraries/LibHTML/DOM/Document.cpp b/Libraries/LibHTML/DOM/Document.cpp
index 4262bca329..9b0cde1ad0 100644
--- a/Libraries/LibHTML/DOM/Document.cpp
+++ b/Libraries/LibHTML/DOM/Document.cpp
@@ -98,10 +98,12 @@ String Document::title() const
void Document::attach_to_frame(Badge<Frame>, Frame& frame)
{
m_frame = frame.make_weak_ptr();
+ layout();
}
void Document::detach_from_frame(Badge<Frame>, Frame&)
{
+ m_layout_root = nullptr;
m_frame = nullptr;
}
@@ -149,8 +151,15 @@ URL Document::complete_url(const String& string) const
return url;
}
+void Document::layout()
+{
+ m_layout_root = create_layout_tree(style_resolver(), nullptr);
+ m_layout_root->layout();
+}
+
void Document::invalidate_layout()
{
+ layout();
if (on_invalidate_layout)
on_invalidate_layout();
}
@@ -174,3 +183,8 @@ void Document::set_visited_link_color(Color color)
{
m_visited_link_color = color;
}
+
+const LayoutDocument* Document::layout_node() const
+{
+ return static_cast<const LayoutDocument*>(Node::layout_node());
+}
diff --git a/Libraries/LibHTML/DOM/Document.h b/Libraries/LibHTML/DOM/Document.h
index 8f3947147c..0566298b59 100644
--- a/Libraries/LibHTML/DOM/Document.h
+++ b/Libraries/LibHTML/DOM/Document.h
@@ -14,6 +14,7 @@ class Frame;
class HTMLBodyElement;
class HTMLHtmlElement;
class HTMLHeadElement;
+class LayoutDocument;
class LayoutNode;
class StyleResolver;
class StyleSheet;
@@ -64,11 +65,15 @@ public:
Color visited_link_color() const { return m_visited_link_color; }
void set_visited_link_color(Color);
+ void layout();
+
void invalidate_layout();
Function<void()> on_invalidate_layout;
virtual bool is_child_allowed(const Node&) const override;
+ const LayoutDocument* layout_node() const;
+
private:
virtual RefPtr<LayoutNode> create_layout_node(const StyleResolver&, const StyleProperties* parent_style) const override;
@@ -78,6 +83,8 @@ private:
WeakPtr<Frame> m_frame;
URL m_url;
+ RefPtr<LayoutDocument> m_layout_root;
+
Color m_link_color { Color::Blue };
Color m_active_link_color { Color::Red };
Color m_visited_link_color { Color::Magenta };
diff --git a/Libraries/LibHTML/HtmlView.cpp b/Libraries/LibHTML/HtmlView.cpp
index 6ac1a9ff0b..98197b03b4 100644
--- a/Libraries/LibHTML/HtmlView.cpp
+++ b/Libraries/LibHTML/HtmlView.cpp
@@ -8,6 +8,7 @@
#include <LibHTML/Dump.h>
#include <LibHTML/Frame.h>
#include <LibHTML/HtmlView.h>
+#include <LibHTML/Layout/LayoutDocument.h>
#include <LibHTML/Layout/LayoutNode.h>
#include <LibHTML/Parser/HTMLParser.h>
#include <LibHTML/RenderingContext.h>
@@ -46,24 +47,18 @@ void HtmlView::set_document(Document* document)
m_document = document;
if (m_document) {
- m_document->on_invalidate_layout = [this]() {
- m_layout_root = m_document->create_layout_tree(m_document->style_resolver(), nullptr);
+ m_document->on_invalidate_layout = [this] {
layout_and_sync_size();
update();
};
}
- m_layout_root = nullptr;
-
main_frame().set_document(document);
- if (document)
- m_layout_root = document->create_layout_tree(document->style_resolver(), nullptr);
-
#ifdef HTML_DEBUG
if (document != nullptr) {
dbgprintf("\033[33;1mLayout tree before layout:\033[0m\n");
- ::dump_tree(*m_layout_root);
+ ::dump_tree(*layout_root());
}
#endif
@@ -73,16 +68,16 @@ void HtmlView::set_document(Document* document)
void HtmlView::layout_and_sync_size()
{
- if (!m_layout_root)
+ if (!document())
return;
main_frame().set_size(available_size());
- m_layout_root->layout();
- set_content_size(m_layout_root->rect().size());
+ document()->layout();
+ set_content_size(layout_root()->rect().size());
#ifdef HTML_DEBUG
dbgprintf("\033[33;1mLayout tree after layout:\033[0m\n");
- ::dump_tree(*m_layout_root);
+ ::dump_tree(*layout_root());
#endif
}
@@ -100,7 +95,7 @@ void HtmlView::paint_event(GPaintEvent& event)
painter.add_clip_rect(widget_inner_rect());
painter.add_clip_rect(event.rect());
- if (!m_layout_root) {
+ if (!layout_root()) {
painter.fill_rect(event.rect(), background_color());
return;
}
@@ -112,17 +107,17 @@ void HtmlView::paint_event(GPaintEvent& event)
RenderingContext context { painter };
context.set_should_show_line_box_borders(m_should_show_line_box_borders);
- m_layout_root->render(context);
+ layout_root()->render(context);
}
void HtmlView::mousemove_event(GMouseEvent& event)
{
- if (!m_layout_root)
+ if (!layout_root())
return GScrollableWidget::mousemove_event(event);
bool hovered_node_changed = false;
bool is_hovering_link = false;
- auto result = m_layout_root->hit_test(to_content_position(event.position()));
+ auto result = layout_root()->hit_test(to_content_position(event.position()));
if (result.layout_node) {
auto* node = result.layout_node->node();
hovered_node_changed = node != m_document->hovered_node();
@@ -154,11 +149,11 @@ void HtmlView::mousemove_event(GMouseEvent& event)
void HtmlView::mousedown_event(GMouseEvent& event)
{
- if (!m_layout_root)
+ if (!layout_root())
return GScrollableWidget::mousemove_event(event);
bool hovered_node_changed = false;
- auto result = m_layout_root->hit_test(to_content_position(event.position()));
+ auto result = layout_root()->hit_test(to_content_position(event.position()));
if (result.layout_node) {
auto* node = result.layout_node->node();
hovered_node_changed = node != m_document->hovered_node();
@@ -205,3 +200,15 @@ void HtmlView::load(const URL& url)
on_title_change(document->title());
});
}
+
+const LayoutDocument* HtmlView::layout_root() const
+{
+ return document() ? document()->layout_node() : nullptr;
+}
+
+LayoutDocument* HtmlView::layout_root()
+{
+ if (!document())
+ return nullptr;
+ return const_cast<LayoutDocument*>(document()->layout_node());
+}
diff --git a/Libraries/LibHTML/HtmlView.h b/Libraries/LibHTML/HtmlView.h
index 3d147b8f7e..5c47d1d591 100644
--- a/Libraries/LibHTML/HtmlView.h
+++ b/Libraries/LibHTML/HtmlView.h
@@ -15,6 +15,9 @@ public:
const Document* document() const { return m_document; }
void set_document(Document*);
+ const LayoutDocument* layout_root() const;
+ LayoutDocument* layout_root();
+
Frame& main_frame() { return *m_main_frame; }
const Frame& main_frame() const { return *m_main_frame; }
@@ -42,7 +45,6 @@ private:
RefPtr<Frame> m_main_frame;
RefPtr<Document> m_document;
- RefPtr<LayoutNode> m_layout_root;
bool m_should_show_line_box_borders { false };
};
diff --git a/Libraries/LibHTML/Layout/LayoutNode.cpp b/Libraries/LibHTML/Layout/LayoutNode.cpp
index 031d8a454c..1de30df602 100644
--- a/Libraries/LibHTML/Layout/LayoutNode.cpp
+++ b/Libraries/LibHTML/Layout/LayoutNode.cpp
@@ -17,7 +17,7 @@ LayoutNode::LayoutNode(const Node* node)
LayoutNode::~LayoutNode()
{
- if (m_node)
+ if (m_node && m_node->layout_node() == this)
m_node->set_layout_node({}, nullptr);
}