Selaa lähdekoodia

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.
Andreas Kling 5 vuotta sitten
vanhempi
commit
38ada2d102

+ 10 - 7
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)

+ 4 - 3
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;

+ 6 - 3
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())
 {
 }

+ 11 - 2
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;