diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-10-13 12:34:25 +0200 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-10-13 12:43:31 +0200 |
commit | 49ac0c2e24ef00dae096c836a1429e03460a0cc7 (patch) | |
tree | 03b622a7f73e38f1589c94a1f43d84106296e345 | |
parent | 48ef1d1bd1df6650a7406c7e747061c8de91915c (diff) | |
download | serenity-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.cpp | 1 | ||||
-rw-r--r-- | Libraries/LibHTML/DOM/Document.cpp | 14 | ||||
-rw-r--r-- | Libraries/LibHTML/DOM/Document.h | 7 | ||||
-rw-r--r-- | Libraries/LibHTML/HtmlView.cpp | 43 | ||||
-rw-r--r-- | Libraries/LibHTML/HtmlView.h | 4 | ||||
-rw-r--r-- | Libraries/LibHTML/Layout/LayoutNode.cpp | 2 |
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); } |