LibHTML: Add a Frame class and use it for document layout width

Each HtmlView now has a main_frame(), which represents the main frame
of the web page. Frame inherits from TreeNode<Frame>, which will allow
us to someday implement a Frame tree (to support the <frame> element.)
This commit is contained in:
Andreas Kling 2019-10-04 15:50:04 +02:00
parent b1758ae2b3
commit 7bc9310170
9 changed files with 101 additions and 8 deletions

View file

@ -4,6 +4,7 @@
#include <LibHTML/DOM/HTMLHeadElement.h>
#include <LibHTML/DOM/HTMLHtmlElement.h>
#include <LibHTML/DOM/HTMLTitleElement.h>
#include <LibHTML/Frame.h>
#include <LibHTML/Layout/LayoutDocument.h>
#include <stdio.h>
@ -63,3 +64,12 @@ String Document::title() const
return title_element->text_content();
}
void Document::attach_to_frame(Badge<Frame>, Frame& frame)
{
m_frame = frame.make_weak_ptr();
}
void Document::detach_from_frame(Badge<Frame>, Frame&)
{
}

View file

@ -3,10 +3,12 @@
#include <AK/NonnullRefPtrVector.h>
#include <AK/OwnPtr.h>
#include <AK/String.h>
#include <AK/WeakPtr.h>
#include <LibHTML/CSS/StyleResolver.h>
#include <LibHTML/CSS/StyleSheet.h>
#include <LibHTML/DOM/ParentNode.h>
class Frame;
class HTMLHtmlElement;
class HTMLHeadElement;
class LayoutNode;
@ -36,8 +38,15 @@ public:
String title() const;
void attach_to_frame(Badge<Frame>, Frame&);
void detach_from_frame(Badge<Frame>, Frame&);
Frame* frame() { return m_frame.ptr(); }
const Frame* frame() const { return m_frame.ptr(); }
private:
OwnPtr<StyleResolver> m_style_resolver;
NonnullRefPtrVector<StyleSheet> m_sheets;
RefPtr<Node> m_hovered_node;
WeakPtr<Frame> m_frame;
};

View file

@ -0,0 +1,31 @@
#include <LibHTML/DOM/Document.h>
#include <LibHTML/Frame.h>
Frame::Frame()
{
}
Frame::~Frame()
{
}
void Frame::set_document(Document* document)
{
if (m_document == document)
return;
if (m_document)
m_document->detach_from_frame({}, *this);
m_document = document;
if (m_document)
m_document->attach_to_frame({}, *this);
}
void Frame::set_size(const Size& size)
{
if (m_size == size)
return;
m_size = size;
}

31
Libraries/LibHTML/Frame.h Normal file
View file

@ -0,0 +1,31 @@
#pragma once
#include <AK/Noncopyable.h>
#include <AK/RefPtr.h>
#include <AK/Weakable.h>
#include <LibDraw/Size.h>
#include <LibHTML/TreeNode.h>
class Document;
class Frame
: public TreeNode<Frame>
, public Weakable<Frame> {
public:
static NonnullRefPtr<Frame> create() { return adopt(*new Frame); }
~Frame();
const Document* document() const { return m_document; }
Document* document() { return m_document; }
void set_document(Document*);
const Size& size() const { return m_size; }
void set_size(const Size&);
private:
Frame();
RefPtr<Document> m_document;
Size m_size;
};

View file

@ -4,6 +4,7 @@
#include <LibHTML/DOM/Element.h>
#include <LibHTML/DOM/HTMLAnchorElement.h>
#include <LibHTML/Dump.h>
#include <LibHTML/Frame.h>
#include <LibHTML/HtmlView.h>
#include <LibHTML/Layout/LayoutNode.h>
#include <LibHTML/RenderingContext.h>
@ -11,6 +12,7 @@
HtmlView::HtmlView(GWidget* parent)
: GScrollableWidget(parent)
, m_main_frame(Frame::create())
{
set_frame_shape(FrameShape::Container);
set_frame_shadow(FrameShadow::Sunken);
@ -19,12 +21,18 @@ HtmlView::HtmlView(GWidget* parent)
set_background_color(Color::White);
}
HtmlView::~HtmlView()
{
}
void HtmlView::set_document(Document* document)
{
if (document == m_document)
return;
m_document = document;
main_frame().set_document(document);
if (document == nullptr)
m_layout_root = nullptr;
else
@ -46,7 +54,7 @@ void HtmlView::layout_and_sync_size()
if (!m_layout_root)
return;
m_layout_root->style().size().set_width(available_size().width());
main_frame().set_size(available_size());
m_layout_root->layout();
set_content_size(m_layout_root->rect().size());

View file

@ -3,15 +3,20 @@
#include <LibGUI/GScrollableWidget.h>
#include <LibHTML/DOM/Document.h>
class Frame;
class HtmlView : public GScrollableWidget {
C_OBJECT(HtmlView)
public:
virtual ~HtmlView() override {}
virtual ~HtmlView() override;
Document* document() { return m_document; }
const Document* document() const { return m_document; }
void set_document(Document*);
Frame& main_frame() { return *m_main_frame; }
const Frame& main_frame() const { return *m_main_frame; }
Function<void(const String&)> on_link_click;
Function<void(const String&)> on_title_change;
@ -26,6 +31,7 @@ protected:
private:
void layout_and_sync_size();
RefPtr<Frame> m_main_frame;
RefPtr<Document> m_document;
RefPtr<LayoutNode> m_layout_root;
};

View file

@ -16,9 +16,6 @@ public:
const LengthBox& padding() const { return m_padding; }
const LengthBox& border() const { return m_border; }
const Size& size() const { return m_size; }
Size& size() { return m_size; }
struct PixelBox {
int top;
int right;
@ -32,6 +29,4 @@ private:
LengthBox m_margin;
LengthBox m_padding;
LengthBox m_border;
Size m_size;
};

View file

@ -1,3 +1,4 @@
#include <LibHTML/Frame.h>
#include <LibHTML/Layout/LayoutDocument.h>
LayoutDocument::LayoutDocument(const Document& document, NonnullRefPtr<StyleProperties> style_properties)
@ -11,7 +12,8 @@ LayoutDocument::~LayoutDocument()
void LayoutDocument::layout()
{
rect().set_width(style().size().width());
ASSERT(document().frame());
rect().set_width(document().frame()->size().width());
LayoutNode::layout();

View file

@ -31,6 +31,7 @@ LIBHTML_OBJS = \
Layout/LineBox.o \
Layout/LineBoxFragment.o \
HtmlView.o \
Frame.o \
Dump.o
GENERATED_SOURCES = \