From 38ada2d102e3c5622ab20b94f0c606304c2aa145 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sat, 6 Jun 2020 15:08:36 +0200 Subject: LibWeb: Delay sub-Frame construction until host Document is attached While we're parsing a new document, we don't have a Frame to grab at. We now use the Node::document_did_attach_to_frame() notification hook to delay subframe construction. With this, subframes now always have a valid reference to their enclosing main frame. --- Libraries/LibWeb/DOM/HTMLIFrameElement.cpp | 17 ++++++++++------- Libraries/LibWeb/DOM/HTMLIFrameElement.h | 7 ++++--- Libraries/LibWeb/Frame.cpp | 9 ++++++--- Libraries/LibWeb/Frame.h | 13 +++++++++++-- 4 files changed, 31 insertions(+), 15 deletions(-) diff --git a/Libraries/LibWeb/DOM/HTMLIFrameElement.cpp b/Libraries/LibWeb/DOM/HTMLIFrameElement.cpp index a929ac1405..d35e0207e4 100644 --- a/Libraries/LibWeb/DOM/HTMLIFrameElement.cpp +++ b/Libraries/LibWeb/DOM/HTMLIFrameElement.cpp @@ -44,7 +44,6 @@ namespace Web { HTMLIFrameElement::HTMLIFrameElement(Document& document, const FlyString& tag_name) : HTMLElement(document, tag_name) { - m_hosted_frame = Frame::create_subframe(); } HTMLIFrameElement::~HTMLIFrameElement() @@ -57,14 +56,18 @@ RefPtr HTMLIFrameElement::create_layout_node(const StyleProperties* return adopt(*new LayoutFrame(*this, move(style))); } -void HTMLIFrameElement::parse_attribute(const FlyString& name, const String& value) +void HTMLIFrameElement::document_did_attach_to_frame(Frame& frame) { - HTMLElement::parse_attribute(name, value); - - if (name == HTML::AttributeNames::src) { - load_src(value); + ASSERT(!m_hosted_frame); + m_hosted_frame = Frame::create_subframe(*this, frame.main_frame()); + auto src = attribute(HTML::AttributeNames::src); + if (src.is_null()) return; - } + load_src(src); +} + +void HTMLIFrameElement::document_will_detach_from_frame(Frame&) +{ } void HTMLIFrameElement::load_src(const String& value) diff --git a/Libraries/LibWeb/DOM/HTMLIFrameElement.h b/Libraries/LibWeb/DOM/HTMLIFrameElement.h index 0a209e2f3f..f984eac0e9 100644 --- a/Libraries/LibWeb/DOM/HTMLIFrameElement.h +++ b/Libraries/LibWeb/DOM/HTMLIFrameElement.h @@ -30,7 +30,7 @@ namespace Web { -class HTMLIFrameElement : public HTMLElement { +class HTMLIFrameElement final : public HTMLElement { public: HTMLIFrameElement(Document&, const FlyString& tag_name); virtual ~HTMLIFrameElement() override; @@ -40,9 +40,10 @@ public: Frame* hosted_frame() { return m_hosted_frame; } const Frame* hosted_frame() const { return m_hosted_frame; } - virtual void parse_attribute(const FlyString& name, const String& value) override; - private: + virtual void document_did_attach_to_frame(Frame&) override; + virtual void document_will_detach_from_frame(Frame&) override; + void load_src(const String&); RefPtr m_hosted_frame; diff --git a/Libraries/LibWeb/Frame.cpp b/Libraries/LibWeb/Frame.cpp index ebe06e62b0..8985e2ede0 100644 --- a/Libraries/LibWeb/Frame.cpp +++ b/Libraries/LibWeb/Frame.cpp @@ -32,13 +32,16 @@ namespace Web { -Frame::Frame() - : m_loader(*this) +Frame::Frame(Element& host_element, Frame& main_frame) + : m_main_frame(main_frame) + , m_loader(*this) + , m_host_element(host_element.make_weak_ptr()) { } Frame::Frame(PageView& page_view) - : m_loader(*this) + : m_main_frame(*this) + , m_loader(*this) , m_page_view(page_view.make_weak_ptr()) { } diff --git a/Libraries/LibWeb/Frame.h b/Libraries/LibWeb/Frame.h index 637ebbfbb7..0a8ae556e6 100644 --- a/Libraries/LibWeb/Frame.h +++ b/Libraries/LibWeb/Frame.h @@ -43,7 +43,7 @@ class PageView; class Frame : public TreeNode { public: - static NonnullRefPtr create_subframe() { return adopt(*new Frame); } + static NonnullRefPtr create_subframe(Element& host_element, Frame& main_frame) { return adopt(*new Frame(host_element, main_frame)); } static NonnullRefPtr create(PageView& page_view) { return adopt(*new Frame(page_view)); } ~Frame(); @@ -76,12 +76,21 @@ public: void scroll_to_anchor(const String&); + Frame& main_frame() { return m_main_frame; } + const Frame& main_frame() const { return m_main_frame; } + + Element* host_element() { return m_host_element; } + const Element* host_element() const { return m_host_element; } + private: - Frame(); + explicit Frame(Element& host_element, Frame& main_frame); explicit Frame(PageView&); + Frame& m_main_frame; + FrameLoader m_loader; + WeakPtr m_host_element; WeakPtr m_page_view; RefPtr m_document; Gfx::Size m_size; -- cgit v1.2.3