refacto and use Element.toInterface

This commit is contained in:
Pierre Tachoire
2025-08-01 17:44:13 +02:00
parent 425f62607b
commit 8d7c35d034
4 changed files with 32 additions and 21 deletions

View File

@@ -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

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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)) },