From cd446e5e9c3ad26293f6718ae36d3d2b08fd6194 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 20 Nov 2024 11:43:20 +0100 Subject: [PATCH] LibWeb: Set doctype node immediately while parsing XML document Instead of deferring it to the end of parsing, where scripts that were expecting to look at the doctype may have already run. --- Libraries/LibWeb/XML/XMLDocumentBuilder.cpp | 6 +-- Libraries/LibWeb/XML/XMLDocumentBuilder.h | 2 +- Libraries/LibXML/Parser/Parser.cpp | 6 +-- Libraries/LibXML/Parser/Parser.h | 2 +- .../dom/nodes/Node-nodeName-xhtml.txt | 17 ++++++++ .../dom/nodes/Node-nodeName-xhtml.xhtml | 42 +++++++++++++++++++ 6 files changed, 66 insertions(+), 9 deletions(-) create mode 100644 Tests/LibWeb/Text/expected/wpt-import/dom/nodes/Node-nodeName-xhtml.txt create mode 100644 Tests/LibWeb/Text/input/wpt-import/dom/nodes/Node-nodeName-xhtml.xhtml diff --git a/Libraries/LibWeb/XML/XMLDocumentBuilder.cpp b/Libraries/LibWeb/XML/XMLDocumentBuilder.cpp index 3e8b1be02fd..2f739d0f722 100644 --- a/Libraries/LibWeb/XML/XMLDocumentBuilder.cpp +++ b/Libraries/LibWeb/XML/XMLDocumentBuilder.cpp @@ -62,7 +62,7 @@ void XMLDocumentBuilder::set_source(ByteString source) m_document->set_source(MUST(String::from_byte_string(source))); } -void XMLDocumentBuilder::set_doctype(XML::Doctype doctype) +void XMLDocumentBuilder::doctype(XML::Doctype const& doctype) { if (m_document->doctype()) { return; @@ -73,13 +73,13 @@ void XMLDocumentBuilder::set_doctype(XML::Doctype doctype) document_type->set_name(name); if (doctype.external_id.has_value()) { - auto external_id = doctype.external_id.release_value(); + auto const& external_id = *doctype.external_id; auto system_id = MUST(AK::String::from_byte_string(external_id.system_id.system_literal)); document_type->set_system_id(system_id); if (external_id.public_id.has_value()) { - auto public_id = MUST(AK::String::from_byte_string(external_id.public_id.release_value().public_literal)); + auto public_id = MUST(AK::String::from_byte_string(external_id.public_id->public_literal)); document_type->set_public_id(public_id); } } diff --git a/Libraries/LibWeb/XML/XMLDocumentBuilder.h b/Libraries/LibWeb/XML/XMLDocumentBuilder.h index 3571e4862bd..d67a50f7a0a 100644 --- a/Libraries/LibWeb/XML/XMLDocumentBuilder.h +++ b/Libraries/LibWeb/XML/XMLDocumentBuilder.h @@ -31,7 +31,7 @@ public: private: virtual void set_source(ByteString) override; - virtual void set_doctype(XML::Doctype) override; + virtual void doctype(XML::Doctype const&) override; virtual void element_start(XML::Name const& name, HashMap const& attributes) override; virtual void element_end(XML::Name const& name) override; virtual void text(StringView data) override; diff --git a/Libraries/LibXML/Parser/Parser.cpp b/Libraries/LibXML/Parser/Parser.cpp index aa0503cf14b..87d7f03e929 100644 --- a/Libraries/LibXML/Parser/Parser.cpp +++ b/Libraries/LibXML/Parser/Parser.cpp @@ -182,9 +182,6 @@ ErrorOr Parser::parse_with_listener(Listener& listener) if (result.is_error()) m_listener->error(result.error()); m_listener->document_end(); - if (m_doctype.has_value()) { - m_listener->set_doctype(m_doctype.release_value()); - } m_root_node.clear(); return result; } @@ -621,7 +618,8 @@ ErrorOr Parser::parse_doctype_decl() TRY(expect(">"sv)); rollback.disarm(); - m_doctype = move(doctype); + if (m_listener) + m_listener->doctype(doctype); return {}; } diff --git a/Libraries/LibXML/Parser/Parser.h b/Libraries/LibXML/Parser/Parser.h index 2fb9e6f905f..481570cadc7 100644 --- a/Libraries/LibXML/Parser/Parser.h +++ b/Libraries/LibXML/Parser/Parser.h @@ -34,9 +34,9 @@ struct Listener { virtual ~Listener() { } virtual void set_source(ByteString) { } - virtual void set_doctype(XML::Doctype) { } virtual void document_start() { } virtual void document_end() { } + virtual void doctype(Doctype const&) { } virtual void element_start(Name const&, HashMap const&) { } virtual void element_end(Name const&) { } virtual void text(StringView) { } diff --git a/Tests/LibWeb/Text/expected/wpt-import/dom/nodes/Node-nodeName-xhtml.txt b/Tests/LibWeb/Text/expected/wpt-import/dom/nodes/Node-nodeName-xhtml.txt new file mode 100644 index 00000000000..4bc2af0f4ff --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/dom/nodes/Node-nodeName-xhtml.txt @@ -0,0 +1,17 @@ +Summary + +Harness status: OK + +Rerun + +Found 7 tests + +7 Pass +Details +Result Test Name MessagePass For Element nodes, nodeName should return the same as tagName. +Pass For Text nodes, nodeName should return "#text". +Pass For ProcessingInstruction nodes, nodeName should return the target. +Pass For Comment nodes, nodeName should return "#comment". +Pass For Document nodes, nodeName should return "#document". +Pass For DocumentType nodes, nodeName should return the name. +Pass For DocumentFragment nodes, nodeName should return "#document-fragment". \ No newline at end of file diff --git a/Tests/LibWeb/Text/input/wpt-import/dom/nodes/Node-nodeName-xhtml.xhtml b/Tests/LibWeb/Text/input/wpt-import/dom/nodes/Node-nodeName-xhtml.xhtml new file mode 100644 index 00000000000..5cb29d7a5da --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/dom/nodes/Node-nodeName-xhtml.xhtml @@ -0,0 +1,42 @@ + + + +Node.nodeName + + + + +
+ + +