Skip to content

Commit d99b49e

Browse files
committed
add Tag.fromString to get element tag from tagname
1 parent e0f079b commit d99b49e

File tree

2 files changed

+99
-69
lines changed

2 files changed

+99
-69
lines changed

src/browser/html/elements.zig

Lines changed: 72 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1109,77 +1109,80 @@ pub const HTMLVideoElement = struct {
11091109
};
11101110

11111111
pub fn toInterface(comptime T: type, e: *parser.Element) !T {
1112-
const elem: *align(@alignOf(*parser.Element)) parser.Element = @alignCast(e);
1113-
const tag = try parser.elementHTMLGetTagType(@as(*parser.ElementHTML, @ptrCast(elem)));
1112+
const tagname = try parser.elementGetTagName(e) orelse {
1113+
// in case of null tagname, return an uknonwn HTMLElement.
1114+
return .{ .HTMLUnknownElement = @as(*parser.Unknown, @ptrCast(e)) };
1115+
};
1116+
const tag = try parser.Tag.fromString(tagname);
11141117

11151118
return switch (tag) {
1116-
.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(elem)) },
1117-
.a => .{ .HTMLAnchorElement = @as(*parser.Anchor, @ptrCast(elem)) },
1118-
.applet => .{ .HTMLAppletElement = @as(*parser.Applet, @ptrCast(elem)) },
1119-
.area => .{ .HTMLAreaElement = @as(*parser.Area, @ptrCast(elem)) },
1120-
.audio => .{ .HTMLAudioElement = @as(*parser.Audio, @ptrCast(elem)) },
1121-
.base => .{ .HTMLBaseElement = @as(*parser.Base, @ptrCast(elem)) },
1122-
.body => .{ .HTMLBodyElement = @as(*parser.Body, @ptrCast(elem)) },
1123-
.br => .{ .HTMLBRElement = @as(*parser.BR, @ptrCast(elem)) },
1124-
.button => .{ .HTMLButtonElement = @as(*parser.Button, @ptrCast(elem)) },
1125-
.canvas => .{ .HTMLCanvasElement = @as(*parser.Canvas, @ptrCast(elem)) },
1126-
.dl => .{ .HTMLDListElement = @as(*parser.DList, @ptrCast(elem)) },
1127-
.data => .{ .HTMLDataElement = @as(*parser.Data, @ptrCast(elem)) },
1128-
.datalist => .{ .HTMLDataListElement = @as(*parser.DataList, @ptrCast(elem)) },
1129-
.dialog => .{ .HTMLDialogElement = @as(*parser.Dialog, @ptrCast(elem)) },
1130-
.dir => .{ .HTMLDirectoryElement = @as(*parser.Directory, @ptrCast(elem)) },
1131-
.div => .{ .HTMLDivElement = @as(*parser.Div, @ptrCast(elem)) },
1132-
.embed => .{ .HTMLEmbedElement = @as(*parser.Embed, @ptrCast(elem)) },
1133-
.fieldset => .{ .HTMLFieldSetElement = @as(*parser.FieldSet, @ptrCast(elem)) },
1134-
.font => .{ .HTMLFontElement = @as(*parser.Font, @ptrCast(elem)) },
1135-
.form => .{ .HTMLFormElement = @as(*parser.Form, @ptrCast(elem)) },
1136-
.frame => .{ .HTMLFrameElement = @as(*parser.Frame, @ptrCast(elem)) },
1137-
.frameset => .{ .HTMLFrameSetElement = @as(*parser.FrameSet, @ptrCast(elem)) },
1138-
.hr => .{ .HTMLHRElement = @as(*parser.HR, @ptrCast(elem)) },
1139-
.head => .{ .HTMLHeadElement = @as(*parser.Head, @ptrCast(elem)) },
1140-
.h1, .h2, .h3, .h4, .h5, .h6 => .{ .HTMLHeadingElement = @as(*parser.Heading, @ptrCast(elem)) },
1141-
.html => .{ .HTMLHtmlElement = @as(*parser.Html, @ptrCast(elem)) },
1142-
.iframe => .{ .HTMLIFrameElement = @as(*parser.IFrame, @ptrCast(elem)) },
1143-
.img => .{ .HTMLImageElement = @as(*parser.Image, @ptrCast(elem)) },
1144-
.input => .{ .HTMLInputElement = @as(*parser.Input, @ptrCast(elem)) },
1145-
.li => .{ .HTMLLIElement = @as(*parser.LI, @ptrCast(elem)) },
1146-
.label => .{ .HTMLLabelElement = @as(*parser.Label, @ptrCast(elem)) },
1147-
.legend => .{ .HTMLLegendElement = @as(*parser.Legend, @ptrCast(elem)) },
1148-
.link => .{ .HTMLLinkElement = @as(*parser.Link, @ptrCast(elem)) },
1149-
.map => .{ .HTMLMapElement = @as(*parser.Map, @ptrCast(elem)) },
1150-
.meta => .{ .HTMLMetaElement = @as(*parser.Meta, @ptrCast(elem)) },
1151-
.meter => .{ .HTMLMeterElement = @as(*parser.Meter, @ptrCast(elem)) },
1152-
.ins, .del => .{ .HTMLModElement = @as(*parser.Mod, @ptrCast(elem)) },
1153-
.ol => .{ .HTMLOListElement = @as(*parser.OList, @ptrCast(elem)) },
1154-
.object => .{ .HTMLObjectElement = @as(*parser.Object, @ptrCast(elem)) },
1155-
.optgroup => .{ .HTMLOptGroupElement = @as(*parser.OptGroup, @ptrCast(elem)) },
1156-
.option => .{ .HTMLOptionElement = @as(*parser.Option, @ptrCast(elem)) },
1157-
.output => .{ .HTMLOutputElement = @as(*parser.Output, @ptrCast(elem)) },
1158-
.p => .{ .HTMLParagraphElement = @as(*parser.Paragraph, @ptrCast(elem)) },
1159-
.param => .{ .HTMLParamElement = @as(*parser.Param, @ptrCast(elem)) },
1160-
.picture => .{ .HTMLPictureElement = @as(*parser.Picture, @ptrCast(elem)) },
1161-
.pre => .{ .HTMLPreElement = @as(*parser.Pre, @ptrCast(elem)) },
1162-
.progress => .{ .HTMLProgressElement = @as(*parser.Progress, @ptrCast(elem)) },
1163-
.blockquote, .q => .{ .HTMLQuoteElement = @as(*parser.Quote, @ptrCast(elem)) },
1164-
.script => .{ .HTMLScriptElement = @as(*parser.Script, @ptrCast(elem)) },
1165-
.select => .{ .HTMLSelectElement = @as(*parser.Select, @ptrCast(elem)) },
1166-
.source => .{ .HTMLSourceElement = @as(*parser.Source, @ptrCast(elem)) },
1167-
.span => .{ .HTMLSpanElement = @as(*parser.Span, @ptrCast(elem)) },
1168-
.style => .{ .HTMLStyleElement = @as(*parser.Style, @ptrCast(elem)) },
1169-
.table => .{ .HTMLTableElement = @as(*parser.Table, @ptrCast(elem)) },
1170-
.caption => .{ .HTMLTableCaptionElement = @as(*parser.TableCaption, @ptrCast(elem)) },
1171-
.th, .td => .{ .HTMLTableCellElement = @as(*parser.TableCell, @ptrCast(elem)) },
1172-
.col, .colgroup => .{ .HTMLTableColElement = @as(*parser.TableCol, @ptrCast(elem)) },
1173-
.tr => .{ .HTMLTableRowElement = @as(*parser.TableRow, @ptrCast(elem)) },
1174-
.thead, .tbody, .tfoot => .{ .HTMLTableSectionElement = @as(*parser.TableSection, @ptrCast(elem)) },
1175-
.template => .{ .HTMLTemplateElement = @as(*parser.Template, @ptrCast(elem)) },
1176-
.textarea => .{ .HTMLTextAreaElement = @as(*parser.TextArea, @ptrCast(elem)) },
1177-
.time => .{ .HTMLTimeElement = @as(*parser.Time, @ptrCast(elem)) },
1178-
.title => .{ .HTMLTitleElement = @as(*parser.Title, @ptrCast(elem)) },
1179-
.track => .{ .HTMLTrackElement = @as(*parser.Track, @ptrCast(elem)) },
1180-
.ul => .{ .HTMLUListElement = @as(*parser.UList, @ptrCast(elem)) },
1181-
.video => .{ .HTMLVideoElement = @as(*parser.Video, @ptrCast(elem)) },
1182-
.undef => .{ .HTMLUnknownElement = @as(*parser.Unknown, @ptrCast(elem)) },
1119+
.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)) },
1120+
.a => .{ .HTMLAnchorElement = @as(*parser.Anchor, @ptrCast(e)) },
1121+
.applet => .{ .HTMLAppletElement = @as(*parser.Applet, @ptrCast(e)) },
1122+
.area => .{ .HTMLAreaElement = @as(*parser.Area, @ptrCast(e)) },
1123+
.audio => .{ .HTMLAudioElement = @as(*parser.Audio, @ptrCast(e)) },
1124+
.base => .{ .HTMLBaseElement = @as(*parser.Base, @ptrCast(e)) },
1125+
.body => .{ .HTMLBodyElement = @as(*parser.Body, @ptrCast(e)) },
1126+
.br => .{ .HTMLBRElement = @as(*parser.BR, @ptrCast(e)) },
1127+
.button => .{ .HTMLButtonElement = @as(*parser.Button, @ptrCast(e)) },
1128+
.canvas => .{ .HTMLCanvasElement = @as(*parser.Canvas, @ptrCast(e)) },
1129+
.dl => .{ .HTMLDListElement = @as(*parser.DList, @ptrCast(e)) },
1130+
.data => .{ .HTMLDataElement = @as(*parser.Data, @ptrCast(e)) },
1131+
.datalist => .{ .HTMLDataListElement = @as(*parser.DataList, @ptrCast(e)) },
1132+
.dialog => .{ .HTMLDialogElement = @as(*parser.Dialog, @ptrCast(e)) },
1133+
.dir => .{ .HTMLDirectoryElement = @as(*parser.Directory, @ptrCast(e)) },
1134+
.div => .{ .HTMLDivElement = @as(*parser.Div, @ptrCast(e)) },
1135+
.embed => .{ .HTMLEmbedElement = @as(*parser.Embed, @ptrCast(e)) },
1136+
.fieldset => .{ .HTMLFieldSetElement = @as(*parser.FieldSet, @ptrCast(e)) },
1137+
.font => .{ .HTMLFontElement = @as(*parser.Font, @ptrCast(e)) },
1138+
.form => .{ .HTMLFormElement = @as(*parser.Form, @ptrCast(e)) },
1139+
.frame => .{ .HTMLFrameElement = @as(*parser.Frame, @ptrCast(e)) },
1140+
.frameset => .{ .HTMLFrameSetElement = @as(*parser.FrameSet, @ptrCast(e)) },
1141+
.hr => .{ .HTMLHRElement = @as(*parser.HR, @ptrCast(e)) },
1142+
.head => .{ .HTMLHeadElement = @as(*parser.Head, @ptrCast(e)) },
1143+
.h1, .h2, .h3, .h4, .h5, .h6 => .{ .HTMLHeadingElement = @as(*parser.Heading, @ptrCast(e)) },
1144+
.html => .{ .HTMLHtmlElement = @as(*parser.Html, @ptrCast(e)) },
1145+
.iframe => .{ .HTMLIFrameElement = @as(*parser.IFrame, @ptrCast(e)) },
1146+
.img => .{ .HTMLImageElement = @as(*parser.Image, @ptrCast(e)) },
1147+
.input => .{ .HTMLInputElement = @as(*parser.Input, @ptrCast(e)) },
1148+
.li => .{ .HTMLLIElement = @as(*parser.LI, @ptrCast(e)) },
1149+
.label => .{ .HTMLLabelElement = @as(*parser.Label, @ptrCast(e)) },
1150+
.legend => .{ .HTMLLegendElement = @as(*parser.Legend, @ptrCast(e)) },
1151+
.link => .{ .HTMLLinkElement = @as(*parser.Link, @ptrCast(e)) },
1152+
.map => .{ .HTMLMapElement = @as(*parser.Map, @ptrCast(e)) },
1153+
.meta => .{ .HTMLMetaElement = @as(*parser.Meta, @ptrCast(e)) },
1154+
.meter => .{ .HTMLMeterElement = @as(*parser.Meter, @ptrCast(e)) },
1155+
.ins, .del => .{ .HTMLModElement = @as(*parser.Mod, @ptrCast(e)) },
1156+
.ol => .{ .HTMLOListElement = @as(*parser.OList, @ptrCast(e)) },
1157+
.object => .{ .HTMLObjectElement = @as(*parser.Object, @ptrCast(e)) },
1158+
.optgroup => .{ .HTMLOptGroupElement = @as(*parser.OptGroup, @ptrCast(e)) },
1159+
.option => .{ .HTMLOptionElement = @as(*parser.Option, @ptrCast(e)) },
1160+
.output => .{ .HTMLOutputElement = @as(*parser.Output, @ptrCast(e)) },
1161+
.p => .{ .HTMLParagraphElement = @as(*parser.Paragraph, @ptrCast(e)) },
1162+
.param => .{ .HTMLParamElement = @as(*parser.Param, @ptrCast(e)) },
1163+
.picture => .{ .HTMLPictureElement = @as(*parser.Picture, @ptrCast(e)) },
1164+
.pre => .{ .HTMLPreElement = @as(*parser.Pre, @ptrCast(e)) },
1165+
.progress => .{ .HTMLProgressElement = @as(*parser.Progress, @ptrCast(e)) },
1166+
.blockquote, .q => .{ .HTMLQuoteElement = @as(*parser.Quote, @ptrCast(e)) },
1167+
.script => .{ .HTMLScriptElement = @as(*parser.Script, @ptrCast(e)) },
1168+
.select => .{ .HTMLSelectElement = @as(*parser.Select, @ptrCast(e)) },
1169+
.source => .{ .HTMLSourceElement = @as(*parser.Source, @ptrCast(e)) },
1170+
.span => .{ .HTMLSpanElement = @as(*parser.Span, @ptrCast(e)) },
1171+
.style => .{ .HTMLStyleElement = @as(*parser.Style, @ptrCast(e)) },
1172+
.table => .{ .HTMLTableElement = @as(*parser.Table, @ptrCast(e)) },
1173+
.caption => .{ .HTMLTableCaptionElement = @as(*parser.TableCaption, @ptrCast(e)) },
1174+
.th, .td => .{ .HTMLTableCellElement = @as(*parser.TableCell, @ptrCast(e)) },
1175+
.col, .colgroup => .{ .HTMLTableColElement = @as(*parser.TableCol, @ptrCast(e)) },
1176+
.tr => .{ .HTMLTableRowElement = @as(*parser.TableRow, @ptrCast(e)) },
1177+
.thead, .tbody, .tfoot => .{ .HTMLTableSectionElement = @as(*parser.TableSection, @ptrCast(e)) },
1178+
.template => .{ .HTMLTemplateElement = @as(*parser.Template, @ptrCast(e)) },
1179+
.textarea => .{ .HTMLTextAreaElement = @as(*parser.TextArea, @ptrCast(e)) },
1180+
.time => .{ .HTMLTimeElement = @as(*parser.Time, @ptrCast(e)) },
1181+
.title => .{ .HTMLTitleElement = @as(*parser.Title, @ptrCast(e)) },
1182+
.track => .{ .HTMLTrackElement = @as(*parser.Track, @ptrCast(e)) },
1183+
.ul => .{ .HTMLUListElement = @as(*parser.UList, @ptrCast(e)) },
1184+
.video => .{ .HTMLVideoElement = @as(*parser.Video, @ptrCast(e)) },
1185+
.undef => .{ .HTMLUnknownElement = @as(*parser.Unknown, @ptrCast(e)) },
11831186
};
11841187
}
11851188

src/browser/netsurf.zig

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,24 @@ pub const Tag = enum(u8) {
328328
else => upperName(@tagName(tag)),
329329
};
330330
}
331+
332+
pub fn fromString(tagname: []const u8) !Tag {
333+
inline for (@typeInfo(Tag).@"enum".fields) |field| {
334+
if (std.ascii.eqlIgnoreCase(field.name, tagname)) {
335+
return @enumFromInt(field.value);
336+
}
337+
}
338+
339+
return error.Invalid;
340+
}
341+
342+
const testing = @import("../testing.zig");
343+
test "Tag.elementTag" {
344+
try testing.expect(try Tag.fromString("ABBR") == .abbr);
345+
try testing.expect(try Tag.fromString("abbr") == .abbr);
346+
347+
try testing.expect(Tag.fromString("foo") == error.Invalid);
348+
}
331349
};
332350

333351
// DOMException
@@ -1577,6 +1595,15 @@ fn elementVtable(elem: *Element) c.dom_element_vtable {
15771595
return getVtable(c.dom_element_vtable, Element, elem);
15781596
}
15791597

1598+
pub fn elementGetTagName(elem: *Element) !?[]const u8 {
1599+
var s: ?*String = undefined;
1600+
const err = elementVtable(elem).dom_element_get_tag_name.?(elem, &s);
1601+
try DOMErr(err);
1602+
if (s == null) return null;
1603+
1604+
return strToData(s.?);
1605+
}
1606+
15801607
pub fn elementGetAttribute(elem: *Element, name: []const u8) !?[]const u8 {
15811608
var s: ?*String = undefined;
15821609
const err = elementVtable(elem).dom_element_get_attribute.?(elem, try strFromData(name), &s);

0 commit comments

Comments
 (0)