mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-05-03 17:58:49 +00:00
To streamline the layout tree and remove irrelevant data from classes that don't need it, this patch adds two new LayoutNode subclasses. LayoutNodeWithStyleAndBoxModelMetrics should be inherited by any layout node that cares about box model metrics (margin, border, and padding.) LayoutBox should be inherited by any layout node that can have a rect. This makes LayoutText significantly smaller (from 140 to 40 bytes) and clarifies a lot of things about the layout tree. I'm also adding next_sibling() and previous_sibling() overloads to LayoutBlock that return a LayoutBlock*. This is okay since blocks only ever have block siblings. Do also note that the semantics of is<T> slightly change in this patch: is<T>(nullptr) now returns true, to facilitate allowing to<T>(nullptr).
79 lines
1.7 KiB
C++
79 lines
1.7 KiB
C++
#include <LibGUI/GPainter.h>
|
|
#include <LibHTML/DOM/Document.h>
|
|
#include <LibHTML/DOM/Element.h>
|
|
#include <LibHTML/Frame.h>
|
|
#include <LibHTML/Layout/LayoutBlock.h>
|
|
#include <LibHTML/Layout/LayoutNode.h>
|
|
|
|
LayoutNode::LayoutNode(const Node* node)
|
|
: m_node(node)
|
|
{
|
|
if (m_node)
|
|
m_node->set_layout_node({}, this);
|
|
}
|
|
|
|
LayoutNode::~LayoutNode()
|
|
{
|
|
if (m_node && m_node->layout_node() == this)
|
|
m_node->set_layout_node({}, nullptr);
|
|
}
|
|
|
|
void LayoutNode::layout()
|
|
{
|
|
for_each_child([](auto& child) {
|
|
child.layout();
|
|
});
|
|
}
|
|
|
|
const LayoutBlock* LayoutNode::containing_block() const
|
|
{
|
|
for (auto* ancestor = parent(); ancestor; ancestor = ancestor->parent()) {
|
|
if (is<LayoutBlock>(*ancestor))
|
|
return to<LayoutBlock>(ancestor);
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
void LayoutNode::render(RenderingContext& context)
|
|
{
|
|
if (!is_visible())
|
|
return;
|
|
|
|
// TODO: render our border
|
|
for_each_child([&](auto& child) {
|
|
child.render(context);
|
|
});
|
|
}
|
|
|
|
HitTestResult LayoutNode::hit_test(const Point& position) const
|
|
{
|
|
HitTestResult result;
|
|
for_each_child([&](auto& child) {
|
|
auto child_result = child.hit_test(position);
|
|
if (child_result.layout_node)
|
|
result = child_result;
|
|
});
|
|
return result;
|
|
}
|
|
|
|
const Document& LayoutNode::document() const
|
|
{
|
|
if (is_anonymous())
|
|
return parent()->document();
|
|
return node()->document();
|
|
}
|
|
|
|
void LayoutNode::split_into_lines(LayoutBlock& container)
|
|
{
|
|
for_each_child([&](auto& child) {
|
|
if (child.is_inline()) {
|
|
child.split_into_lines(container);
|
|
} else {
|
|
// FIXME: Support block children of inlines.
|
|
}
|
|
});
|
|
}
|
|
|
|
void LayoutNode::set_needs_display()
|
|
{
|
|
}
|