allow other XML MIMEs in parseFromString

This commit is contained in:
Halil Durak
2026-01-07 14:34:35 +03:00
parent 56d89895a8
commit 612b3a26b7

View File

@@ -19,9 +19,13 @@
const std = @import("std"); const std = @import("std");
const js = @import("../js/js.zig"); const js = @import("../js/js.zig");
const Page = @import("../Page.zig"); const Page = @import("../Page.zig");
const Parser = @import("../parser/Parser.zig");
const HTMLDocument = @import("HTMLDocument.zig"); const HTMLDocument = @import("HTMLDocument.zig");
const XMLDocument = @import("XMLDocument.zig"); const XMLDocument = @import("XMLDocument.zig");
const ProcessingInstruction = @import("../webapi/cdata/ProcessingInstruction.zig");
const DOMParser = @This(); const DOMParser = @This();
@@ -40,46 +44,65 @@ pub fn parseFromString(
mime_type: []const u8, mime_type: []const u8,
page: *Page, page: *Page,
) !HTMLDocumentOrXMLDocument { ) !HTMLDocumentOrXMLDocument {
if (std.mem.eql(u8, mime_type, "text/html")) { const maybe_target_mime = std.meta.stringToEnum(enum {
// Create a new HTMLDocument @"text/html",
const doc = try page._factory.document(HTMLDocument{ @"text/xml",
._proto = undefined, @"application/xml",
}); @"application/xhtml+xml",
@"image/svg+xml",
}, mime_type);
var normalized = std.mem.trim(u8, html, &std.ascii.whitespace); if (maybe_target_mime) |target_mime| switch (target_mime) {
if (normalized.len == 0) { .@"text/html" => {
normalized = "<html></html>"; // Create a new HTMLDocument
} const doc = try page._factory.document(HTMLDocument{
._proto = undefined,
});
// Parse HTML into the document var normalized = std.mem.trim(u8, html, &std.ascii.whitespace);
const Parser = @import("../parser/Parser.zig"); if (normalized.len == 0) {
var parser = Parser.init(page.arena, doc.asNode(), page); normalized = "<html></html>";
parser.parse(normalized); }
if (parser.err) |pe| { // Parse HTML into the document
return pe.err; var parser = Parser.init(page.arena, doc.asNode(), page);
} parser.parse(normalized);
return .{ .html_document = doc }; if (parser.err) |pe| {
} return pe.err;
}
if (std.mem.eql(u8, mime_type, "text/xml")) { return .{ .html_document = doc };
// Create a new XMLDocument. },
const doc = try page._factory.document(XMLDocument{ else => {
._proto = undefined, // Create a new XMLDocument.
}); const doc = try page._factory.document(XMLDocument{
._proto = undefined,
});
// Parse XML into XMLDocument. // Parse XML into XMLDocument.
const Parser = @import("../parser/Parser.zig"); const doc_node = doc.asNode();
var parser = Parser.init(page.arena, doc.asNode(), page); var parser = Parser.init(page.arena, doc_node, page);
parser.parseXML(html); parser.parseXML(html);
if (parser.err) |pe| { if (parser.err) |pe| {
return pe.err; return pe.err;
} }
return .{ .xml_document = doc }; // If first node is a `ProcessingInstruction`, skip it.
} const first_child = doc_node.firstChild() orelse {
// Parsing should fail if there aren't any nodes.
unreachable;
};
if (first_child.getNodeType() == 7) {
// We're sure that firstChild exist, this cannot fail.
_ = doc_node.removeChild(first_child, page) catch unreachable;
}
return .{ .xml_document = doc };
},
};
return error.NotSupported; return error.NotSupported;
} }