diff options
author | Andreas Kling <kling@serenityos.org> | 2020-06-06 15:08:36 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-06-06 16:36:18 +0200 |
commit | 38ada2d102e3c5622ab20b94f0c606304c2aa145 (patch) | |
tree | f9676ff155b34f851f732da074c4ab4eddb57b55 | |
parent | 285a4165f39078db5d52645c2dc5d0861c4f38ac (diff) | |
download | serenity-38ada2d102e3c5622ab20b94f0c606304c2aa145.zip |
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.
-rw-r--r-- | Libraries/LibWeb/DOM/HTMLIFrameElement.cpp | 17 | ||||
-rw-r--r-- | Libraries/LibWeb/DOM/HTMLIFrameElement.h | 7 | ||||
-rw-r--r-- | Libraries/LibWeb/Frame.cpp | 9 | ||||
-rw-r--r-- | 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<LayoutNode> 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<Frame> 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<Frame> { public: - static NonnullRefPtr<Frame> create_subframe() { return adopt(*new Frame); } + static NonnullRefPtr<Frame> create_subframe(Element& host_element, Frame& main_frame) { return adopt(*new Frame(host_element, main_frame)); } static NonnullRefPtr<Frame> 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<Element> m_host_element; WeakPtr<PageView> m_page_view; RefPtr<Document> m_document; Gfx::Size m_size; |