From a4de30de5ac456cba960a5414e4d8b5ebf94eebf Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sat, 29 Oct 2022 13:06:24 +0200 Subject: [PATCH] LibWeb: Update "appropriate template contents owner document" AO This was moved from HTMLTemplateElement to Document at some point, so let's match the spec and move it here too. --- Userland/Libraries/LibWeb/DOM/Document.cpp | 26 ++++++++++++++ Userland/Libraries/LibWeb/DOM/Document.h | 6 ++-- .../LibWeb/HTML/HTMLTemplateElement.cpp | 35 +++++++------------ .../LibWeb/HTML/HTMLTemplateElement.h | 4 +-- 4 files changed, 42 insertions(+), 29 deletions(-) diff --git a/Userland/Libraries/LibWeb/DOM/Document.cpp b/Userland/Libraries/LibWeb/DOM/Document.cpp index 7f64a17337..ac1d9ea8ed 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.cpp +++ b/Userland/Libraries/LibWeb/DOM/Document.cpp @@ -327,6 +327,7 @@ void Document::visit_edges(Cell::Visitor& visitor) visitor.visit(m_implementation.ptr()); visitor.visit(m_current_script.ptr()); visitor.visit(m_associated_inert_template_document.ptr()); + visitor.visit(m_appropriate_template_contents_owner_document); visitor.visit(m_pending_parsing_blocking_script.ptr()); visitor.visit(m_history.ptr()); @@ -2265,4 +2266,29 @@ void Document::did_stop_being_active_document_in_browsing_context(Badge Document::appropriate_template_contents_owner_document() +{ + // 1. If doc is not a Document created by this algorithm, then: + if (!created_for_appropriate_template_contents()) { + // 1. If doc does not yet have an associated inert template document, then: + if (!m_associated_inert_template_document) { + // 1. Let new doc be a new Document (whose browsing context is null). This is "a Document created by this algorithm" for the purposes of the step above. + auto new_document = DOM::Document::create(realm()); + new_document->m_created_for_appropriate_template_contents = true; + + // 2. If doc is an HTML document, mark new doc as an HTML document also. + if (document_type() == Type::HTML) + new_document->set_document_type(Type::HTML); + + // 3. Let doc's associated inert template document be new doc. + m_associated_inert_template_document = new_document; + } + // 2. Set doc to doc's associated inert template document. + return *m_associated_inert_template_document; + } + // 2. Return doc. + return *this; +} + } diff --git a/Userland/Libraries/LibWeb/DOM/Document.h b/Userland/Libraries/LibWeb/DOM/Document.h index 1ba0988cb6..b1b48c910c 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.h +++ b/Userland/Libraries/LibWeb/DOM/Document.h @@ -277,11 +277,8 @@ public: void set_active_element(Element*); bool created_for_appropriate_template_contents() const { return m_created_for_appropriate_template_contents; } - void set_created_for_appropriate_template_contents(bool value) { m_created_for_appropriate_template_contents = value; } - Document* associated_inert_template_document() { return m_associated_inert_template_document.ptr(); } - Document const* associated_inert_template_document() const { return m_associated_inert_template_document.ptr(); } - void set_associated_inert_template_document(Document& document) { m_associated_inert_template_document = &document; } + JS::NonnullGCPtr appropriate_template_contents_owner_document(); String ready_state() const; void update_readiness(HTML::DocumentReadyState); @@ -505,6 +502,7 @@ private: bool m_created_for_appropriate_template_contents { false }; JS::GCPtr m_associated_inert_template_document; + JS::GCPtr m_appropriate_template_contents_owner_document; HTML::DocumentReadyState m_readiness { HTML::DocumentReadyState::Loading }; String m_content_type { "application/xml" }; diff --git a/Userland/Libraries/LibWeb/HTML/HTMLTemplateElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLTemplateElement.cpp index 834e3d85c5..5d7ecfd01d 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLTemplateElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLTemplateElement.cpp @@ -14,42 +14,31 @@ HTMLTemplateElement::HTMLTemplateElement(DOM::Document& document, DOM::Qualified : HTMLElement(document, move(qualified_name)) { set_prototype(&Bindings::cached_web_prototype(realm(), "HTMLTemplateElement")); - - m_content = heap().allocate(realm(), appropriate_template_contents_owner_document(document)); - m_content->set_host(this); } HTMLTemplateElement::~HTMLTemplateElement() = default; +void HTMLTemplateElement::initialize(JS::Realm& realm) +{ + Base::initialize(realm); + m_content = heap().allocate(realm, m_document->appropriate_template_contents_owner_document()); + m_content->set_host(this); +} + void HTMLTemplateElement::visit_edges(Cell::Visitor& visitor) { Base::visit_edges(visitor); visitor.visit(m_content.ptr()); } -DOM::Document& HTMLTemplateElement::appropriate_template_contents_owner_document(DOM::Document& document) -{ - if (!document.created_for_appropriate_template_contents()) { - if (!document.associated_inert_template_document()) { - auto new_document = DOM::Document::create(realm()); - new_document->set_created_for_appropriate_template_contents(true); - new_document->set_document_type(document.document_type()); - - document.set_associated_inert_template_document(new_document); - } - - return *document.associated_inert_template_document(); - } - - return document; -} - // https://html.spec.whatwg.org/multipage/scripting.html#the-template-element:concept-node-adopt-ext void HTMLTemplateElement::adopted_from(DOM::Document&) { - // NOTE: It seems the spec has been changed since appropriate_template_contents_owner_document was written above. - // That function is now part of document, which ends up returning associated_inert_template_document in the new version anyway. - appropriate_template_contents_owner_document(document()).adopt_node(content()); + // 1. Let doc be node's node document's appropriate template contents owner document. + auto doc = document().appropriate_template_contents_owner_document(); + + // 2. Adopt node's template contents (a DocumentFragment object) into doc. + doc->adopt_node(content()); } // https://html.spec.whatwg.org/multipage/scripting.html#the-template-element:concept-node-clone-ext diff --git a/Userland/Libraries/LibWeb/HTML/HTMLTemplateElement.h b/Userland/Libraries/LibWeb/HTML/HTMLTemplateElement.h index 43e7be4c03..2c22e19480 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLTemplateElement.h +++ b/Userland/Libraries/LibWeb/HTML/HTMLTemplateElement.h @@ -27,9 +27,9 @@ private: HTMLTemplateElement(DOM::Document&, DOM::QualifiedName); virtual bool is_html_template_element() const final { return true; } - virtual void visit_edges(Cell::Visitor&) override; - DOM::Document& appropriate_template_contents_owner_document(DOM::Document&); + virtual void initialize(JS::Realm&) override; + virtual void visit_edges(Cell::Visitor&) override; JS::GCPtr m_content; };