diff --git a/src/browser/js/bridge.zig b/src/browser/js/bridge.zig
index 4fb65b70..08bb93ca 100644
--- a/src/browser/js/bridge.zig
+++ b/src/browser/js/bridge.zig
@@ -489,6 +489,7 @@ pub const JsApis = flattenTypes(&.{
@import("../webapi/DOMTreeWalker.zig"),
@import("../webapi/DOMNodeIterator.zig"),
@import("../webapi/DOMRect.zig"),
+ @import("../webapi/DOMParser.zig"),
@import("../webapi/NodeFilter.zig"),
@import("../webapi/Element.zig"),
@import("../webapi/element/DOMStringMap.zig"),
diff --git a/src/browser/tests/domparser.html b/src/browser/tests/domparser.html
new file mode 100644
index 00000000..390f7bfe
--- /dev/null
+++ b/src/browser/tests/domparser.html
@@ -0,0 +1,121 @@
+
+
+
+
+
+
+
+
diff --git a/src/browser/webapi/DOMParser.zig b/src/browser/webapi/DOMParser.zig
new file mode 100644
index 00000000..df87f915
--- /dev/null
+++ b/src/browser/webapi/DOMParser.zig
@@ -0,0 +1,57 @@
+const std = @import("std");
+
+const js = @import("../js/js.zig");
+const Page = @import("../Page.zig");
+const Document = @import("Document.zig");
+const HTMLDocument = @import("HTMLDocument.zig");
+
+const DOMParser = @This();
+// @ZIGDOM support empty structs
+_: u8 = 0,
+
+pub fn init() DOMParser {
+ return .{};
+}
+
+pub fn parseFromString(self: *const DOMParser, html: []const u8, mime_type: []const u8, page: *Page) !*HTMLDocument {
+ _ = self;
+
+ // For now, only support text/html
+ if (!std.mem.eql(u8, mime_type, "text/html")) {
+ return error.NotSupported;
+ }
+
+ // Create a new HTMLDocument
+ const doc = try page._factory.document(HTMLDocument{
+ ._proto = undefined,
+ });
+
+ // Parse HTML into the document
+ const Parser = @import("../parser/Parser.zig");
+ var parser = Parser.init(page.arena, doc.asNode(), page);
+ parser.parse(html);
+
+ if (parser.err) |pe| {
+ return pe.err;
+ }
+
+ return doc;
+}
+
+pub const JsApi = struct {
+ pub const bridge = js.Bridge(DOMParser);
+
+ pub const Meta = struct {
+ pub const name = "DOMParser";
+ pub const prototype_chain = bridge.prototypeChain();
+ pub var class_id: bridge.ClassId = undefined;
+ };
+
+ pub const constructor = bridge.constructor(DOMParser.init, .{});
+ pub const parseFromString = bridge.function(DOMParser.parseFromString, .{});
+};
+
+const testing = @import("../../testing.zig");
+test "WebApi: DOMParser" {
+ try testing.htmlRunner("domparser.html", .{});
+}
diff --git a/src/browser/webapi/Document.zig b/src/browser/webapi/Document.zig
index 5d58d3ab..767acf32 100644
--- a/src/browser/webapi/Document.zig
+++ b/src/browser/webapi/Document.zig
@@ -122,8 +122,11 @@ pub fn querySelectorAll(self: *Document, input: []const u8, page: *Page) !*Selec
return Selector.querySelectorAll(self.asNode(), input, page);
}
-pub fn className(_: *const Document) []const u8 {
- return "[object Document]";
+pub fn className(self: *const Document) []const u8 {
+ return switch (self._type) {
+ .generic => "[object Document]",
+ .html => "[object HTMLDocument]",
+ };
}
pub fn getImplementation(_: *const Document) DOMImplementation {