From 16c74cf3b4e3a3194ac4dc689ae2175b6832d95a Mon Sep 17 00:00:00 2001 From: Pierre Tachoire Date: Thu, 7 Aug 2025 12:47:02 +0200 Subject: [PATCH 1/2] element: fix toInterface for webcomponents The webcomponents tag can be anything. But we must return them as HTMLElement for HTML documents. --- src/browser/dom/element.zig | 14 ++++++++++++-- src/browser/polyfill/webcomponents.zig | 2 ++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/browser/dom/element.zig b/src/browser/dom/element.zig index af556b46..6ab70278 100644 --- a/src/browser/dom/element.zig +++ b/src/browser/dom/element.zig @@ -60,14 +60,24 @@ pub const Element = struct { pub fn toInterfaceT(comptime T: type, e: *parser.Element) !T { const tagname = try parser.elementGetTagName(e) orelse { - // in case of null tagname, return the element as it. + // If the owner's document is HTML, assume we have an HTMLElement. + const doc = try parser.nodeOwnerDocument(parser.elementToNode(e)); + if (doc != null and !doc.?.is_html) { + return .{ .HTMLElement = @as(*parser.ElementHTML, @ptrCast(e)) }; + } + return .{ .Element = e }; }; // TODO SVGElement and MathML are not supported yet. const tag = parser.Tag.fromString(tagname) catch { - // if the tag is invalid, we don't have an HTMLElement. + // If the owner's document is HTML, assume we have an HTMLElement. + const doc = try parser.nodeOwnerDocument(parser.elementToNode(e)); + if (doc != null and doc.?.is_html) { + return .{ .HTMLElement = @as(*parser.ElementHTML, @ptrCast(e)) }; + } + return .{ .Element = e }; }; diff --git a/src/browser/polyfill/webcomponents.zig b/src/browser/polyfill/webcomponents.zig index e38f63f4..2f4f44cd 100644 --- a/src/browser/polyfill/webcomponents.zig +++ b/src/browser/polyfill/webcomponents.zig @@ -61,5 +61,7 @@ test "Browser.webcomponents" { }, .{ "main.innerHTML", "connected" }, + .{ "document.createElement('lightpanda-test').dataset", "[object DataSet]" }, + .{ "document.createElement('lightpanda-test.x').dataset", "[object DataSet]" }, }, .{}); } From 29378c57ea092a8a226eeb3ee4404bf2f7ce14ef Mon Sep 17 00:00:00 2001 From: Pierre Tachoire Date: Thu, 7 Aug 2025 12:54:18 +0200 Subject: [PATCH 2/2] node: cast the libdom document depending its type --- src/browser/dom/node.zig | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/browser/dom/node.zig b/src/browser/dom/node.zig index 25c15431..08c8f42e 100644 --- a/src/browser/dom/node.zig +++ b/src/browser/dom/node.zig @@ -75,7 +75,14 @@ pub const Node = struct { .text => .{ .Text = @as(*parser.Text, @ptrCast(node)) }, .cdata_section => .{ .CDATASection = @as(*parser.CDATASection, @ptrCast(node)) }, .processing_instruction => .{ .ProcessingInstruction = @as(*parser.ProcessingInstruction, @ptrCast(node)) }, - .document => .{ .HTMLDocument = @as(*parser.DocumentHTML, @ptrCast(node)) }, + .document => blk: { + const doc: *parser.Document = @ptrCast(node); + if (doc.is_html) { + break :blk .{ .HTMLDocument = @as(*parser.DocumentHTML, @ptrCast(node)) }; + } + + break :blk .{ .Document = doc }; + }, .document_type => .{ .DocumentType = @as(*parser.DocumentType, @ptrCast(node)) }, .attribute => .{ .Attr = @as(*parser.Attribute, @ptrCast(node)) }, .document_fragment => .{ .DocumentFragment = @as(*parser.DocumentFragment, @ptrCast(node)) },