From 8d7c35d034c415a573ecabaf9b21983076dbf8b5 Mon Sep 17 00:00:00 2001 From: Pierre Tachoire Date: Fri, 1 Aug 2025 17:44:13 +0200 Subject: [PATCH] refacto and use Element.toInterface --- src/browser/dom/character_data.zig | 11 ++++++----- src/browser/dom/element.zig | 23 +++++++++++++++++++---- src/browser/dom/node.zig | 8 ++++---- src/browser/html/elements.zig | 11 +++-------- 4 files changed, 32 insertions(+), 21 deletions(-) diff --git a/src/browser/dom/character_data.zig b/src/browser/dom/character_data.zig index 871b77ec..774572a3 100644 --- a/src/browser/dom/character_data.zig +++ b/src/browser/dom/character_data.zig @@ -24,7 +24,8 @@ const Node = @import("node.zig").Node; const Comment = @import("comment.zig").Comment; const Text = @import("text.zig"); const ProcessingInstruction = @import("processing_instruction.zig").ProcessingInstruction; -const HTMLElem = @import("../html/elements.zig"); +const Element = @import("element.zig").Element; +const ElementUnion = @import("element.zig").Union; // CharacterData interfaces pub const Interfaces = .{ @@ -49,20 +50,20 @@ pub const CharacterData = struct { return try parser.characterDataLength(self); } - pub fn get_nextElementSibling(self: *parser.CharacterData) !?HTMLElem.Union { + pub fn get_nextElementSibling(self: *parser.CharacterData) !?ElementUnion { const res = try parser.nodeNextElementSibling(parser.characterDataToNode(self)); if (res == null) { return null; } - return try HTMLElem.toInterface(HTMLElem.Union, res.?); + return try Element.toInterface(res.?); } - pub fn get_previousElementSibling(self: *parser.CharacterData) !?HTMLElem.Union { + pub fn get_previousElementSibling(self: *parser.CharacterData) !?ElementUnion { const res = try parser.nodePreviousElementSibling(parser.characterDataToNode(self)); if (res == null) { return null; } - return try HTMLElem.toInterface(HTMLElem.Union, res.?); + return try Element.toInterface(res.?); } // Read/Write attributes diff --git a/src/browser/dom/element.zig b/src/browser/dom/element.zig index 054ba57e..af556b46 100644 --- a/src/browser/dom/element.zig +++ b/src/browser/dom/element.zig @@ -55,8 +55,23 @@ pub const Element = struct { }; pub fn toInterface(e: *parser.Element) !Union { - return try HTMLElem.toInterface(Union, e); - // SVGElement and MathML are not supported yet. + return toInterfaceT(Union, e); + } + + 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. + 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. + return .{ .Element = e }; + }; + + return HTMLElem.toInterfaceFromTag(T, e, tag); } // JS funcs @@ -344,13 +359,13 @@ pub const Element = struct { pub fn get_previousElementSibling(self: *parser.Element) !?Union { const res = try parser.nodePreviousElementSibling(parser.elementToNode(self)); if (res == null) return null; - return try HTMLElem.toInterface(HTMLElem.Union, res.?); + return try toInterface(res.?); } pub fn get_nextElementSibling(self: *parser.Element) !?Union { const res = try parser.nodeNextElementSibling(parser.elementToNode(self)); if (res == null) return null; - return try HTMLElem.toInterface(HTMLElem.Union, res.?); + return try toInterface(res.?); } fn getElementById(self: *parser.Element, id: []const u8) !?*parser.Node { diff --git a/src/browser/dom/node.zig b/src/browser/dom/node.zig index cca301ce..25c15431 100644 --- a/src/browser/dom/node.zig +++ b/src/browser/dom/node.zig @@ -29,6 +29,7 @@ const EventTarget = @import("event_target.zig").EventTarget; const Attr = @import("attribute.zig").Attr; const CData = @import("character_data.zig"); const Element = @import("element.zig").Element; +const ElementUnion = @import("element.zig").Union; const NodeList = @import("nodelist.zig").NodeList; const Document = @import("document.zig").Document; const DocumentType = @import("document_type.zig").DocumentType; @@ -40,7 +41,6 @@ const Walker = @import("walker.zig").WalkerDepthFirst; // HTML const HTML = @import("../html/html.zig"); -const HTMLElem = @import("../html/elements.zig"); // Node interfaces pub const Interfaces = .{ @@ -67,7 +67,7 @@ pub const Node = struct { pub fn toInterface(node: *parser.Node) !Union { return switch (try parser.nodeType(node)) { - .element => try HTMLElem.toInterface( + .element => try Element.toInterfaceT( Union, @as(*parser.Element, @ptrCast(node)), ), @@ -145,12 +145,12 @@ pub const Node = struct { return try Node.toInterface(res.?); } - pub fn get_parentElement(self: *parser.Node) !?HTMLElem.Union { + pub fn get_parentElement(self: *parser.Node) !?ElementUnion { const res = try parser.nodeParentElement(self); if (res == null) { return null; } - return try HTMLElem.toInterface(HTMLElem.Union, @as(*parser.Element, @ptrCast(res.?))); + return try Element.toInterface(res.?); } pub fn get_nodeName(self: *parser.Node) ![]const u8 { diff --git a/src/browser/html/elements.zig b/src/browser/html/elements.zig index 969b3635..e985ca5d 100644 --- a/src/browser/html/elements.zig +++ b/src/browser/html/elements.zig @@ -34,6 +34,7 @@ const CSSStyleDeclaration = @import("../cssom/CSSStyleDeclaration.zig"); // HTMLElement interfaces pub const Interfaces = .{ + Element, HTMLElement, HTMLUnknownElement, HTMLAnchorElement, @@ -639,7 +640,7 @@ pub const HTMLImageElement = struct { pub const prototype = *HTMLImageElement; pub fn constructor(width: ?u32, height: ?u32, page: *const Page) !*parser.Image { - const element = try parser.documentCreateElement(parser.documentHTMLToDocument(page.window.document), "img"); + const element = try parser.documentCreateHTMLElement(parser.documentHTMLToDocument(page.window.document), "img"); const image: *parser.Image = @ptrCast(element); if (width) |width_| try parser.imageSetWidth(image, width_); if (height) |height_| try parser.imageSetHeight(image, height_); @@ -1108,13 +1109,7 @@ pub const HTMLVideoElement = struct { pub const subtype = .node; }; -pub fn toInterface(comptime T: type, e: *parser.Element) !T { - const tagname = try parser.elementGetTagName(e) orelse { - // in case of null tagname, return an uknonwn HTMLElement. - return .{ .HTMLUnknownElement = @as(*parser.Unknown, @ptrCast(e)) }; - }; - const tag = try parser.Tag.fromString(tagname); - +pub fn toInterfaceFromTag(comptime T: type, e: *parser.Element, tag: parser.Tag) !T { return switch (tag) { .abbr, .acronym, .address, .article, .aside, .b, .basefont, .bdi, .bdo, .bgsound, .big, .center, .cite, .code, .dd, .details, .dfn, .dt, .em, .figcaption, .figure, .footer, .header, .hgroup, .i, .isindex, .keygen, .kbd, .main, .mark, .marquee, .menu, .menuitem, .nav, .nobr, .noframes, .noscript, .rp, .rt, .ruby, .s, .samp, .section, .small, .spacer, .strike, .strong, .sub, .summary, .sup, .tt, .u, .wbr, ._var => .{ .HTMLElement = @as(*parser.ElementHTML, @ptrCast(e)) }, .a => .{ .HTMLAnchorElement = @as(*parser.Anchor, @ptrCast(e)) },