From 6742646e89127cda58d42a2f99cfec8fa755e1c4 Mon Sep 17 00:00:00 2001 From: Karl Seguin Date: Thu, 13 Nov 2025 20:57:17 +0800 Subject: [PATCH] DOMParser --- src/browser/js/bridge.zig | 1 + src/browser/tests/domparser.html | 121 +++++++++++++++++++++++++++++++ src/browser/webapi/DOMParser.zig | 57 +++++++++++++++ src/browser/webapi/Document.zig | 7 +- 4 files changed, 184 insertions(+), 2 deletions(-) create mode 100644 src/browser/tests/domparser.html create mode 100644 src/browser/webapi/DOMParser.zig 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 {