diff --git a/Tests/LibWeb/Text/expected/DOM/domparser-parsefromstring-doctype-publicid.txt b/Tests/LibWeb/Text/expected/DOM/domparser-parsefromstring-doctype-publicid.txt
new file mode 100644
index 00000000000..d31f14b7861
--- /dev/null
+++ b/Tests/LibWeb/Text/expected/DOM/domparser-parsefromstring-doctype-publicid.txt
@@ -0,0 +1,3 @@
+PASSED doctype.name
+PASSED doctype.systemId
+PASSED doctype.publicId
diff --git a/Tests/LibWeb/Text/expected/DOM/domparser-parsefromstring-doctype-systemid.txt b/Tests/LibWeb/Text/expected/DOM/domparser-parsefromstring-doctype-systemid.txt
new file mode 100644
index 00000000000..d31f14b7861
--- /dev/null
+++ b/Tests/LibWeb/Text/expected/DOM/domparser-parsefromstring-doctype-systemid.txt
@@ -0,0 +1,3 @@
+PASSED doctype.name
+PASSED doctype.systemId
+PASSED doctype.publicId
diff --git a/Tests/LibWeb/Text/input/DOM/domparser-parsefromstring-doctype-publicid.html b/Tests/LibWeb/Text/input/DOM/domparser-parsefromstring-doctype-publicid.html
new file mode 100644
index 00000000000..c3cb3604e8b
--- /dev/null
+++ b/Tests/LibWeb/Text/input/DOM/domparser-parsefromstring-doctype-publicid.html
@@ -0,0 +1,25 @@
+
+
+
diff --git a/Tests/LibWeb/Text/input/DOM/domparser-parsefromstring-doctype-systemid.html b/Tests/LibWeb/Text/input/DOM/domparser-parsefromstring-doctype-systemid.html
new file mode 100644
index 00000000000..0bffea70030
--- /dev/null
+++ b/Tests/LibWeb/Text/input/DOM/domparser-parsefromstring-doctype-systemid.html
@@ -0,0 +1,25 @@
+
+
+
diff --git a/Userland/Libraries/LibWeb/XML/XMLDocumentBuilder.cpp b/Userland/Libraries/LibWeb/XML/XMLDocumentBuilder.cpp
index d2b3c42e1d1..5f7b273e7d9 100644
--- a/Userland/Libraries/LibWeb/XML/XMLDocumentBuilder.cpp
+++ b/Userland/Libraries/LibWeb/XML/XMLDocumentBuilder.cpp
@@ -4,6 +4,7 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
+#include
#include
#include
#include
@@ -61,6 +62,31 @@ void XMLDocumentBuilder::set_source(ByteString source)
m_document->set_source(MUST(String::from_byte_string(source)));
}
+void XMLDocumentBuilder::set_doctype(XML::Doctype doctype)
+{
+ if (m_document->doctype()) {
+ return;
+ }
+
+ auto document_type = DOM::DocumentType::create(m_document);
+ auto name = MUST(AK::String::from_byte_string(doctype.type));
+ document_type->set_name(name);
+
+ if (doctype.external_id.has_value()) {
+ auto external_id = doctype.external_id.release_value();
+
+ 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));
+ document_type->set_public_id(public_id);
+ }
+ }
+
+ m_document->insert_before(document_type, m_document->first_child(), false);
+}
+
void XMLDocumentBuilder::element_start(const XML::Name& name, HashMap const& attributes)
{
if (m_has_error)
diff --git a/Userland/Libraries/LibWeb/XML/XMLDocumentBuilder.h b/Userland/Libraries/LibWeb/XML/XMLDocumentBuilder.h
index 05a24e3f3e3..2bfe8811e4e 100644
--- a/Userland/Libraries/LibWeb/XML/XMLDocumentBuilder.h
+++ b/Userland/Libraries/LibWeb/XML/XMLDocumentBuilder.h
@@ -31,6 +31,7 @@ public:
private:
virtual void set_source(ByteString) override;
+ virtual void set_doctype(XML::Doctype) 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/Userland/Libraries/LibXML/Parser/Parser.cpp b/Userland/Libraries/LibXML/Parser/Parser.cpp
index 9a6884f8848..23870c27e86 100644
--- a/Userland/Libraries/LibXML/Parser/Parser.cpp
+++ b/Userland/Libraries/LibXML/Parser/Parser.cpp
@@ -182,6 +182,9 @@ 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;
}
diff --git a/Userland/Libraries/LibXML/Parser/Parser.h b/Userland/Libraries/LibXML/Parser/Parser.h
index a6db08f6481..2fb9e6f905f 100644
--- a/Userland/Libraries/LibXML/Parser/Parser.h
+++ b/Userland/Libraries/LibXML/Parser/Parser.h
@@ -34,6 +34,7 @@ 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 element_start(Name const&, HashMap const&) { }