mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-10-29 23:23:28 +00:00
Merge pull request #919 from lightpanda-io/html_element-and-element
Create HTMLElement instead of pure Element
This commit is contained in:
@@ -24,7 +24,8 @@ const Node = @import("node.zig").Node;
|
|||||||
const Comment = @import("comment.zig").Comment;
|
const Comment = @import("comment.zig").Comment;
|
||||||
const Text = @import("text.zig");
|
const Text = @import("text.zig");
|
||||||
const ProcessingInstruction = @import("processing_instruction.zig").ProcessingInstruction;
|
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
|
// CharacterData interfaces
|
||||||
pub const Interfaces = .{
|
pub const Interfaces = .{
|
||||||
@@ -49,20 +50,20 @@ pub const CharacterData = struct {
|
|||||||
return try parser.characterDataLength(self);
|
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));
|
const res = try parser.nodeNextElementSibling(parser.characterDataToNode(self));
|
||||||
if (res == null) {
|
if (res == null) {
|
||||||
return 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));
|
const res = try parser.nodePreviousElementSibling(parser.characterDataToNode(self));
|
||||||
if (res == null) {
|
if (res == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return try HTMLElem.toInterface(HTMLElem.Union, res.?);
|
return try Element.toInterface(res.?);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read/Write attributes
|
// Read/Write attributes
|
||||||
|
|||||||
@@ -66,10 +66,8 @@ pub const Document = struct {
|
|||||||
return DOMImplementation{};
|
return DOMImplementation{};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_documentElement(self: *parser.Document) !?ElementUnion {
|
pub fn get_documentElement(self: *parser.Document) !?*parser.Element {
|
||||||
const e = try parser.documentGetDocumentElement(self);
|
return try parser.documentGetDocumentElement(self);
|
||||||
if (e == null) return null;
|
|
||||||
return try Element.toInterface(e.?);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_documentURI(self: *parser.Document) ![]const u8 {
|
pub fn get_documentURI(self: *parser.Document) ![]const u8 {
|
||||||
|
|||||||
@@ -55,8 +55,23 @@ pub const Element = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub fn toInterface(e: *parser.Element) !Union {
|
pub fn toInterface(e: *parser.Element) !Union {
|
||||||
return try HTMLElem.toInterface(Union, e);
|
return toInterfaceT(Union, e);
|
||||||
// SVGElement and MathML are not supported yet.
|
}
|
||||||
|
|
||||||
|
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
|
// JS funcs
|
||||||
@@ -344,13 +359,13 @@ pub const Element = struct {
|
|||||||
pub fn get_previousElementSibling(self: *parser.Element) !?Union {
|
pub fn get_previousElementSibling(self: *parser.Element) !?Union {
|
||||||
const res = try parser.nodePreviousElementSibling(parser.elementToNode(self));
|
const res = try parser.nodePreviousElementSibling(parser.elementToNode(self));
|
||||||
if (res == null) return null;
|
if (res == null) return null;
|
||||||
return try HTMLElem.toInterface(HTMLElem.Union, res.?);
|
return try toInterface(res.?);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_nextElementSibling(self: *parser.Element) !?Union {
|
pub fn get_nextElementSibling(self: *parser.Element) !?Union {
|
||||||
const res = try parser.nodeNextElementSibling(parser.elementToNode(self));
|
const res = try parser.nodeNextElementSibling(parser.elementToNode(self));
|
||||||
if (res == null) return null;
|
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 {
|
fn getElementById(self: *parser.Element, id: []const u8) !?*parser.Node {
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ const EventTarget = @import("event_target.zig").EventTarget;
|
|||||||
const Attr = @import("attribute.zig").Attr;
|
const Attr = @import("attribute.zig").Attr;
|
||||||
const CData = @import("character_data.zig");
|
const CData = @import("character_data.zig");
|
||||||
const Element = @import("element.zig").Element;
|
const Element = @import("element.zig").Element;
|
||||||
|
const ElementUnion = @import("element.zig").Union;
|
||||||
const NodeList = @import("nodelist.zig").NodeList;
|
const NodeList = @import("nodelist.zig").NodeList;
|
||||||
const Document = @import("document.zig").Document;
|
const Document = @import("document.zig").Document;
|
||||||
const DocumentType = @import("document_type.zig").DocumentType;
|
const DocumentType = @import("document_type.zig").DocumentType;
|
||||||
@@ -40,7 +41,6 @@ const Walker = @import("walker.zig").WalkerDepthFirst;
|
|||||||
|
|
||||||
// HTML
|
// HTML
|
||||||
const HTML = @import("../html/html.zig");
|
const HTML = @import("../html/html.zig");
|
||||||
const HTMLElem = @import("../html/elements.zig");
|
|
||||||
|
|
||||||
// Node interfaces
|
// Node interfaces
|
||||||
pub const Interfaces = .{
|
pub const Interfaces = .{
|
||||||
@@ -67,7 +67,7 @@ pub const Node = struct {
|
|||||||
|
|
||||||
pub fn toInterface(node: *parser.Node) !Union {
|
pub fn toInterface(node: *parser.Node) !Union {
|
||||||
return switch (try parser.nodeType(node)) {
|
return switch (try parser.nodeType(node)) {
|
||||||
.element => try HTMLElem.toInterface(
|
.element => try Element.toInterfaceT(
|
||||||
Union,
|
Union,
|
||||||
@as(*parser.Element, @ptrCast(node)),
|
@as(*parser.Element, @ptrCast(node)),
|
||||||
),
|
),
|
||||||
@@ -145,12 +145,12 @@ pub const Node = struct {
|
|||||||
return try Node.toInterface(res.?);
|
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);
|
const res = try parser.nodeParentElement(self);
|
||||||
if (res == null) {
|
if (res == null) {
|
||||||
return 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 {
|
pub fn get_nodeName(self: *parser.Node) ![]const u8 {
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ pub fn writeNode(node: *parser.Node, opts: Opts, writer: anytype) anyerror!void
|
|||||||
switch (try parser.nodeType(node)) {
|
switch (try parser.nodeType(node)) {
|
||||||
.element => {
|
.element => {
|
||||||
// open the tag
|
// open the tag
|
||||||
const tag_type = try parser.elementHTMLGetTagType(@ptrCast(node));
|
const tag_type = try parser.nodeHTMLGetTagType(node) orelse .undef;
|
||||||
if (tag_type == .script and opts.exclude_scripts) {
|
if (tag_type == .script and opts.exclude_scripts) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -150,7 +150,7 @@ pub fn writeChildren(root: *parser.Node, opts: Opts, writer: anytype) !void {
|
|||||||
// area, base, br, col, embed, hr, img, input, link, meta, source, track, wbr
|
// area, base, br, col, embed, hr, img, input, link, meta, source, track, wbr
|
||||||
// https://html.spec.whatwg.org/#void-elements
|
// https://html.spec.whatwg.org/#void-elements
|
||||||
fn isVoid(elem: *parser.Element) !bool {
|
fn isVoid(elem: *parser.Element) !bool {
|
||||||
const tag = try parser.elementHTMLGetTagType(@as(*parser.ElementHTML, @ptrCast(elem)));
|
const tag = try parser.elementTag(elem);
|
||||||
return switch (tag) {
|
return switch (tag) {
|
||||||
.area, .base, .br, .col, .embed, .hr, .img, .input, .link => true,
|
.area, .base, .br, .col, .embed, .hr, .img, .input, .link => true,
|
||||||
.meta, .source, .track, .wbr => true,
|
.meta, .source, .track, .wbr => true,
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ const CSSStyleDeclaration = @import("../cssom/CSSStyleDeclaration.zig");
|
|||||||
|
|
||||||
// HTMLElement interfaces
|
// HTMLElement interfaces
|
||||||
pub const Interfaces = .{
|
pub const Interfaces = .{
|
||||||
|
Element,
|
||||||
HTMLElement,
|
HTMLElement,
|
||||||
HTMLUnknownElement,
|
HTMLUnknownElement,
|
||||||
HTMLAnchorElement,
|
HTMLAnchorElement,
|
||||||
@@ -1108,78 +1109,75 @@ pub const HTMLVideoElement = struct {
|
|||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn toInterface(comptime T: type, e: *parser.Element) !T {
|
pub fn toInterfaceFromTag(comptime T: type, e: *parser.Element, tag: parser.Tag) !T {
|
||||||
const elem: *align(@alignOf(*parser.Element)) parser.Element = @alignCast(e);
|
|
||||||
const tag = try parser.elementHTMLGetTagType(@as(*parser.ElementHTML, @ptrCast(elem)));
|
|
||||||
|
|
||||||
return switch (tag) {
|
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(elem)) },
|
.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(elem)) },
|
.a => .{ .HTMLAnchorElement = @as(*parser.Anchor, @ptrCast(e)) },
|
||||||
.applet => .{ .HTMLAppletElement = @as(*parser.Applet, @ptrCast(elem)) },
|
.applet => .{ .HTMLAppletElement = @as(*parser.Applet, @ptrCast(e)) },
|
||||||
.area => .{ .HTMLAreaElement = @as(*parser.Area, @ptrCast(elem)) },
|
.area => .{ .HTMLAreaElement = @as(*parser.Area, @ptrCast(e)) },
|
||||||
.audio => .{ .HTMLAudioElement = @as(*parser.Audio, @ptrCast(elem)) },
|
.audio => .{ .HTMLAudioElement = @as(*parser.Audio, @ptrCast(e)) },
|
||||||
.base => .{ .HTMLBaseElement = @as(*parser.Base, @ptrCast(elem)) },
|
.base => .{ .HTMLBaseElement = @as(*parser.Base, @ptrCast(e)) },
|
||||||
.body => .{ .HTMLBodyElement = @as(*parser.Body, @ptrCast(elem)) },
|
.body => .{ .HTMLBodyElement = @as(*parser.Body, @ptrCast(e)) },
|
||||||
.br => .{ .HTMLBRElement = @as(*parser.BR, @ptrCast(elem)) },
|
.br => .{ .HTMLBRElement = @as(*parser.BR, @ptrCast(e)) },
|
||||||
.button => .{ .HTMLButtonElement = @as(*parser.Button, @ptrCast(elem)) },
|
.button => .{ .HTMLButtonElement = @as(*parser.Button, @ptrCast(e)) },
|
||||||
.canvas => .{ .HTMLCanvasElement = @as(*parser.Canvas, @ptrCast(elem)) },
|
.canvas => .{ .HTMLCanvasElement = @as(*parser.Canvas, @ptrCast(e)) },
|
||||||
.dl => .{ .HTMLDListElement = @as(*parser.DList, @ptrCast(elem)) },
|
.dl => .{ .HTMLDListElement = @as(*parser.DList, @ptrCast(e)) },
|
||||||
.data => .{ .HTMLDataElement = @as(*parser.Data, @ptrCast(elem)) },
|
.data => .{ .HTMLDataElement = @as(*parser.Data, @ptrCast(e)) },
|
||||||
.datalist => .{ .HTMLDataListElement = @as(*parser.DataList, @ptrCast(elem)) },
|
.datalist => .{ .HTMLDataListElement = @as(*parser.DataList, @ptrCast(e)) },
|
||||||
.dialog => .{ .HTMLDialogElement = @as(*parser.Dialog, @ptrCast(elem)) },
|
.dialog => .{ .HTMLDialogElement = @as(*parser.Dialog, @ptrCast(e)) },
|
||||||
.dir => .{ .HTMLDirectoryElement = @as(*parser.Directory, @ptrCast(elem)) },
|
.dir => .{ .HTMLDirectoryElement = @as(*parser.Directory, @ptrCast(e)) },
|
||||||
.div => .{ .HTMLDivElement = @as(*parser.Div, @ptrCast(elem)) },
|
.div => .{ .HTMLDivElement = @as(*parser.Div, @ptrCast(e)) },
|
||||||
.embed => .{ .HTMLEmbedElement = @as(*parser.Embed, @ptrCast(elem)) },
|
.embed => .{ .HTMLEmbedElement = @as(*parser.Embed, @ptrCast(e)) },
|
||||||
.fieldset => .{ .HTMLFieldSetElement = @as(*parser.FieldSet, @ptrCast(elem)) },
|
.fieldset => .{ .HTMLFieldSetElement = @as(*parser.FieldSet, @ptrCast(e)) },
|
||||||
.font => .{ .HTMLFontElement = @as(*parser.Font, @ptrCast(elem)) },
|
.font => .{ .HTMLFontElement = @as(*parser.Font, @ptrCast(e)) },
|
||||||
.form => .{ .HTMLFormElement = @as(*parser.Form, @ptrCast(elem)) },
|
.form => .{ .HTMLFormElement = @as(*parser.Form, @ptrCast(e)) },
|
||||||
.frame => .{ .HTMLFrameElement = @as(*parser.Frame, @ptrCast(elem)) },
|
.frame => .{ .HTMLFrameElement = @as(*parser.Frame, @ptrCast(e)) },
|
||||||
.frameset => .{ .HTMLFrameSetElement = @as(*parser.FrameSet, @ptrCast(elem)) },
|
.frameset => .{ .HTMLFrameSetElement = @as(*parser.FrameSet, @ptrCast(e)) },
|
||||||
.hr => .{ .HTMLHRElement = @as(*parser.HR, @ptrCast(elem)) },
|
.hr => .{ .HTMLHRElement = @as(*parser.HR, @ptrCast(e)) },
|
||||||
.head => .{ .HTMLHeadElement = @as(*parser.Head, @ptrCast(elem)) },
|
.head => .{ .HTMLHeadElement = @as(*parser.Head, @ptrCast(e)) },
|
||||||
.h1, .h2, .h3, .h4, .h5, .h6 => .{ .HTMLHeadingElement = @as(*parser.Heading, @ptrCast(elem)) },
|
.h1, .h2, .h3, .h4, .h5, .h6 => .{ .HTMLHeadingElement = @as(*parser.Heading, @ptrCast(e)) },
|
||||||
.html => .{ .HTMLHtmlElement = @as(*parser.Html, @ptrCast(elem)) },
|
.html => .{ .HTMLHtmlElement = @as(*parser.Html, @ptrCast(e)) },
|
||||||
.iframe => .{ .HTMLIFrameElement = @as(*parser.IFrame, @ptrCast(elem)) },
|
.iframe => .{ .HTMLIFrameElement = @as(*parser.IFrame, @ptrCast(e)) },
|
||||||
.img => .{ .HTMLImageElement = @as(*parser.Image, @ptrCast(elem)) },
|
.img => .{ .HTMLImageElement = @as(*parser.Image, @ptrCast(e)) },
|
||||||
.input => .{ .HTMLInputElement = @as(*parser.Input, @ptrCast(elem)) },
|
.input => .{ .HTMLInputElement = @as(*parser.Input, @ptrCast(e)) },
|
||||||
.li => .{ .HTMLLIElement = @as(*parser.LI, @ptrCast(elem)) },
|
.li => .{ .HTMLLIElement = @as(*parser.LI, @ptrCast(e)) },
|
||||||
.label => .{ .HTMLLabelElement = @as(*parser.Label, @ptrCast(elem)) },
|
.label => .{ .HTMLLabelElement = @as(*parser.Label, @ptrCast(e)) },
|
||||||
.legend => .{ .HTMLLegendElement = @as(*parser.Legend, @ptrCast(elem)) },
|
.legend => .{ .HTMLLegendElement = @as(*parser.Legend, @ptrCast(e)) },
|
||||||
.link => .{ .HTMLLinkElement = @as(*parser.Link, @ptrCast(elem)) },
|
.link => .{ .HTMLLinkElement = @as(*parser.Link, @ptrCast(e)) },
|
||||||
.map => .{ .HTMLMapElement = @as(*parser.Map, @ptrCast(elem)) },
|
.map => .{ .HTMLMapElement = @as(*parser.Map, @ptrCast(e)) },
|
||||||
.meta => .{ .HTMLMetaElement = @as(*parser.Meta, @ptrCast(elem)) },
|
.meta => .{ .HTMLMetaElement = @as(*parser.Meta, @ptrCast(e)) },
|
||||||
.meter => .{ .HTMLMeterElement = @as(*parser.Meter, @ptrCast(elem)) },
|
.meter => .{ .HTMLMeterElement = @as(*parser.Meter, @ptrCast(e)) },
|
||||||
.ins, .del => .{ .HTMLModElement = @as(*parser.Mod, @ptrCast(elem)) },
|
.ins, .del => .{ .HTMLModElement = @as(*parser.Mod, @ptrCast(e)) },
|
||||||
.ol => .{ .HTMLOListElement = @as(*parser.OList, @ptrCast(elem)) },
|
.ol => .{ .HTMLOListElement = @as(*parser.OList, @ptrCast(e)) },
|
||||||
.object => .{ .HTMLObjectElement = @as(*parser.Object, @ptrCast(elem)) },
|
.object => .{ .HTMLObjectElement = @as(*parser.Object, @ptrCast(e)) },
|
||||||
.optgroup => .{ .HTMLOptGroupElement = @as(*parser.OptGroup, @ptrCast(elem)) },
|
.optgroup => .{ .HTMLOptGroupElement = @as(*parser.OptGroup, @ptrCast(e)) },
|
||||||
.option => .{ .HTMLOptionElement = @as(*parser.Option, @ptrCast(elem)) },
|
.option => .{ .HTMLOptionElement = @as(*parser.Option, @ptrCast(e)) },
|
||||||
.output => .{ .HTMLOutputElement = @as(*parser.Output, @ptrCast(elem)) },
|
.output => .{ .HTMLOutputElement = @as(*parser.Output, @ptrCast(e)) },
|
||||||
.p => .{ .HTMLParagraphElement = @as(*parser.Paragraph, @ptrCast(elem)) },
|
.p => .{ .HTMLParagraphElement = @as(*parser.Paragraph, @ptrCast(e)) },
|
||||||
.param => .{ .HTMLParamElement = @as(*parser.Param, @ptrCast(elem)) },
|
.param => .{ .HTMLParamElement = @as(*parser.Param, @ptrCast(e)) },
|
||||||
.picture => .{ .HTMLPictureElement = @as(*parser.Picture, @ptrCast(elem)) },
|
.picture => .{ .HTMLPictureElement = @as(*parser.Picture, @ptrCast(e)) },
|
||||||
.pre => .{ .HTMLPreElement = @as(*parser.Pre, @ptrCast(elem)) },
|
.pre => .{ .HTMLPreElement = @as(*parser.Pre, @ptrCast(e)) },
|
||||||
.progress => .{ .HTMLProgressElement = @as(*parser.Progress, @ptrCast(elem)) },
|
.progress => .{ .HTMLProgressElement = @as(*parser.Progress, @ptrCast(e)) },
|
||||||
.blockquote, .q => .{ .HTMLQuoteElement = @as(*parser.Quote, @ptrCast(elem)) },
|
.blockquote, .q => .{ .HTMLQuoteElement = @as(*parser.Quote, @ptrCast(e)) },
|
||||||
.script => .{ .HTMLScriptElement = @as(*parser.Script, @ptrCast(elem)) },
|
.script => .{ .HTMLScriptElement = @as(*parser.Script, @ptrCast(e)) },
|
||||||
.select => .{ .HTMLSelectElement = @as(*parser.Select, @ptrCast(elem)) },
|
.select => .{ .HTMLSelectElement = @as(*parser.Select, @ptrCast(e)) },
|
||||||
.source => .{ .HTMLSourceElement = @as(*parser.Source, @ptrCast(elem)) },
|
.source => .{ .HTMLSourceElement = @as(*parser.Source, @ptrCast(e)) },
|
||||||
.span => .{ .HTMLSpanElement = @as(*parser.Span, @ptrCast(elem)) },
|
.span => .{ .HTMLSpanElement = @as(*parser.Span, @ptrCast(e)) },
|
||||||
.style => .{ .HTMLStyleElement = @as(*parser.Style, @ptrCast(elem)) },
|
.style => .{ .HTMLStyleElement = @as(*parser.Style, @ptrCast(e)) },
|
||||||
.table => .{ .HTMLTableElement = @as(*parser.Table, @ptrCast(elem)) },
|
.table => .{ .HTMLTableElement = @as(*parser.Table, @ptrCast(e)) },
|
||||||
.caption => .{ .HTMLTableCaptionElement = @as(*parser.TableCaption, @ptrCast(elem)) },
|
.caption => .{ .HTMLTableCaptionElement = @as(*parser.TableCaption, @ptrCast(e)) },
|
||||||
.th, .td => .{ .HTMLTableCellElement = @as(*parser.TableCell, @ptrCast(elem)) },
|
.th, .td => .{ .HTMLTableCellElement = @as(*parser.TableCell, @ptrCast(e)) },
|
||||||
.col, .colgroup => .{ .HTMLTableColElement = @as(*parser.TableCol, @ptrCast(elem)) },
|
.col, .colgroup => .{ .HTMLTableColElement = @as(*parser.TableCol, @ptrCast(e)) },
|
||||||
.tr => .{ .HTMLTableRowElement = @as(*parser.TableRow, @ptrCast(elem)) },
|
.tr => .{ .HTMLTableRowElement = @as(*parser.TableRow, @ptrCast(e)) },
|
||||||
.thead, .tbody, .tfoot => .{ .HTMLTableSectionElement = @as(*parser.TableSection, @ptrCast(elem)) },
|
.thead, .tbody, .tfoot => .{ .HTMLTableSectionElement = @as(*parser.TableSection, @ptrCast(e)) },
|
||||||
.template => .{ .HTMLTemplateElement = @as(*parser.Template, @ptrCast(elem)) },
|
.template => .{ .HTMLTemplateElement = @as(*parser.Template, @ptrCast(e)) },
|
||||||
.textarea => .{ .HTMLTextAreaElement = @as(*parser.TextArea, @ptrCast(elem)) },
|
.textarea => .{ .HTMLTextAreaElement = @as(*parser.TextArea, @ptrCast(e)) },
|
||||||
.time => .{ .HTMLTimeElement = @as(*parser.Time, @ptrCast(elem)) },
|
.time => .{ .HTMLTimeElement = @as(*parser.Time, @ptrCast(e)) },
|
||||||
.title => .{ .HTMLTitleElement = @as(*parser.Title, @ptrCast(elem)) },
|
.title => .{ .HTMLTitleElement = @as(*parser.Title, @ptrCast(e)) },
|
||||||
.track => .{ .HTMLTrackElement = @as(*parser.Track, @ptrCast(elem)) },
|
.track => .{ .HTMLTrackElement = @as(*parser.Track, @ptrCast(e)) },
|
||||||
.ul => .{ .HTMLUListElement = @as(*parser.UList, @ptrCast(elem)) },
|
.ul => .{ .HTMLUListElement = @as(*parser.UList, @ptrCast(e)) },
|
||||||
.video => .{ .HTMLVideoElement = @as(*parser.Video, @ptrCast(elem)) },
|
.video => .{ .HTMLVideoElement = @as(*parser.Video, @ptrCast(e)) },
|
||||||
.undef => .{ .HTMLUnknownElement = @as(*parser.Unknown, @ptrCast(elem)) },
|
.undef => .{ .HTMLUnknownElement = @as(*parser.Unknown, @ptrCast(e)) },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -328,6 +328,24 @@ pub const Tag = enum(u8) {
|
|||||||
else => upperName(@tagName(tag)),
|
else => upperName(@tagName(tag)),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn fromString(tagname: []const u8) !Tag {
|
||||||
|
inline for (@typeInfo(Tag).@"enum".fields) |field| {
|
||||||
|
if (std.ascii.eqlIgnoreCase(field.name, tagname)) {
|
||||||
|
return @enumFromInt(field.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return error.Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
const testing = @import("../testing.zig");
|
||||||
|
test "Tag.fromString" {
|
||||||
|
try testing.expect(try Tag.fromString("ABBR") == .abbr);
|
||||||
|
try testing.expect(try Tag.fromString("abbr") == .abbr);
|
||||||
|
|
||||||
|
try testing.expect(Tag.fromString("foo") == error.Invalid);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// DOMException
|
// DOMException
|
||||||
@@ -1410,13 +1428,13 @@ pub inline fn nodeToDocument(node: *Node) *Document {
|
|||||||
return @as(*Document, @ptrCast(node));
|
return @as(*Document, @ptrCast(node));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Combination of nodeToElement + elementHTMLGetTagType
|
// Combination of nodeToElement + elementTag
|
||||||
pub fn nodeHTMLGetTagType(node: *Node) !?Tag {
|
pub fn nodeHTMLGetTagType(node: *Node) !?Tag {
|
||||||
if (try nodeType(node) != .element) {
|
if (try nodeType(node) != .element) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const html_element: *ElementHTML = @ptrCast(node);
|
|
||||||
return try elementHTMLGetTagType(html_element);
|
return try elementTag(@ptrCast(node));
|
||||||
}
|
}
|
||||||
|
|
||||||
// CharacterData
|
// CharacterData
|
||||||
@@ -1577,6 +1595,20 @@ fn elementVtable(elem: *Element) c.dom_element_vtable {
|
|||||||
return getVtable(c.dom_element_vtable, Element, elem);
|
return getVtable(c.dom_element_vtable, Element, elem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn elementTag(elem: *Element) !Tag {
|
||||||
|
const tagname = try elementGetTagName(elem) orelse return .undef;
|
||||||
|
return Tag.fromString(tagname) catch .undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn elementGetTagName(elem: *Element) !?[]const u8 {
|
||||||
|
var s: ?*String = undefined;
|
||||||
|
const err = elementVtable(elem).dom_element_get_tag_name.?(elem, &s);
|
||||||
|
try DOMErr(err);
|
||||||
|
if (s == null) return null;
|
||||||
|
|
||||||
|
return strToData(s.?);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn elementGetAttribute(elem: *Element, name: []const u8) !?[]const u8 {
|
pub fn elementGetAttribute(elem: *Element, name: []const u8) !?[]const u8 {
|
||||||
var s: ?*String = undefined;
|
var s: ?*String = undefined;
|
||||||
const err = elementVtable(elem).dom_element_get_attribute.?(elem, try strFromData(name), &s);
|
const err = elementVtable(elem).dom_element_get_attribute.?(elem, try strFromData(name), &s);
|
||||||
@@ -1770,21 +1802,6 @@ fn elementHTMLVtable(elem_html: *ElementHTML) c.dom_html_element_vtable {
|
|||||||
return getVtable(c.dom_html_element_vtable, ElementHTML, elem_html);
|
return getVtable(c.dom_html_element_vtable, ElementHTML, elem_html);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn elementHTMLGetTagType(elem_html: *ElementHTML) !Tag {
|
|
||||||
var tag_type: c.dom_html_element_type = undefined;
|
|
||||||
const err = elementHTMLVtable(elem_html).dom_html_element_get_tag_type.?(elem_html, &tag_type);
|
|
||||||
try DOMErr(err);
|
|
||||||
|
|
||||||
if (tag_type >= 255) {
|
|
||||||
// This is questionable, but std.meta.intToEnum has more overhead
|
|
||||||
// Added this because this WPT test started to fail once we
|
|
||||||
// introduced an SVGElement:
|
|
||||||
// html/dom/documents/dom-tree-accessors/document.title-09.html
|
|
||||||
return Tag.undef;
|
|
||||||
}
|
|
||||||
return @as(Tag, @enumFromInt(tag_type));
|
|
||||||
}
|
|
||||||
|
|
||||||
// HTMLScriptElement
|
// HTMLScriptElement
|
||||||
|
|
||||||
// scriptToElt is an helper to convert an script to an element.
|
// scriptToElt is an helper to convert an script to an element.
|
||||||
@@ -2139,14 +2156,45 @@ pub inline fn documentCreateDocument(title: ?[]const u8) !*DocumentHTML {
|
|||||||
return doc_html;
|
return doc_html;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn documentCreateElement(doc: *Document, tag_name: []const u8) !*Element {
|
fn documentCreateHTMLElement(doc: *Document, tag_name: []const u8) !*Element {
|
||||||
|
std.debug.assert(doc.is_html);
|
||||||
|
|
||||||
|
var elem: ?*Element = undefined;
|
||||||
|
const err = c._dom_html_document_create_element(doc, try strFromData(tag_name), &elem);
|
||||||
|
try DOMErr(err);
|
||||||
|
return elem.?;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn documentCreateElement(doc: *Document, tag_name: []const u8) !*Element {
|
||||||
|
if (doc.is_html) {
|
||||||
|
return documentCreateHTMLElement(doc, tag_name);
|
||||||
|
}
|
||||||
|
|
||||||
var elem: ?*Element = undefined;
|
var elem: ?*Element = undefined;
|
||||||
const err = documentVtable(doc).dom_document_create_element.?(doc, try strFromData(tag_name), &elem);
|
const err = documentVtable(doc).dom_document_create_element.?(doc, try strFromData(tag_name), &elem);
|
||||||
try DOMErr(err);
|
try DOMErr(err);
|
||||||
return elem.?;
|
return elem.?;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn documentCreateElementNS(doc: *Document, ns: []const u8, tag_name: []const u8) !*Element {
|
fn documentCreateHTMLElementNS(doc: *Document, ns: []const u8, tag_name: []const u8) !*Element {
|
||||||
|
std.debug.assert(doc.is_html);
|
||||||
|
|
||||||
|
var elem: ?*Element = undefined;
|
||||||
|
const err = c._dom_html_document_create_element_ns(
|
||||||
|
doc,
|
||||||
|
try strFromData(ns),
|
||||||
|
try strFromData(tag_name),
|
||||||
|
&elem,
|
||||||
|
);
|
||||||
|
try DOMErr(err);
|
||||||
|
return elem.?;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn documentCreateElementNS(doc: *Document, ns: []const u8, tag_name: []const u8) !*Element {
|
||||||
|
if (doc.is_html) {
|
||||||
|
return documentCreateHTMLElementNS(doc, ns, tag_name);
|
||||||
|
}
|
||||||
|
|
||||||
var elem: ?*Element = undefined;
|
var elem: ?*Element = undefined;
|
||||||
const err = documentVtable(doc).dom_document_create_element_ns.?(
|
const err = documentVtable(doc).dom_document_create_element_ns.?(
|
||||||
doc,
|
doc,
|
||||||
|
|||||||
@@ -365,7 +365,7 @@ pub const Page = struct {
|
|||||||
const current = next.?;
|
const current = next.?;
|
||||||
|
|
||||||
const e = parser.nodeToElement(current);
|
const e = parser.nodeToElement(current);
|
||||||
const tag = try parser.elementHTMLGetTagType(@as(*parser.ElementHTML, @ptrCast(e)));
|
const tag = try parser.elementTag(e);
|
||||||
|
|
||||||
if (tag != .script) {
|
if (tag != .script) {
|
||||||
// ignore non-js script.
|
// ignore non-js script.
|
||||||
@@ -809,7 +809,7 @@ pub const Page = struct {
|
|||||||
if (try parser.elementGetAttribute(element, "form")) |form_id| {
|
if (try parser.elementGetAttribute(element, "form")) |form_id| {
|
||||||
const document = parser.documentHTMLToDocument(self.window.document);
|
const document = parser.documentHTMLToDocument(self.window.document);
|
||||||
const form_element = try parser.documentGetElementById(document, form_id) orelse return null;
|
const form_element = try parser.documentGetElementById(document, form_id) orelse return null;
|
||||||
if (try parser.elementHTMLGetTagType(@ptrCast(form_element)) == .form) {
|
if (try parser.elementTag(@ptrCast(form_element)) == .form) {
|
||||||
return @ptrCast(form_element);
|
return @ptrCast(form_element);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ fn collectForm(form: *parser.Form, submitter_: ?*parser.ElementHTML, page: *Page
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const tag = try parser.elementHTMLGetTagType(@as(*parser.ElementHTML, @ptrCast(element)));
|
const tag = try parser.elementTag(element);
|
||||||
switch (tag) {
|
switch (tag) {
|
||||||
.input => {
|
.input => {
|
||||||
const tpe = try parser.inputGetType(@ptrCast(element));
|
const tpe = try parser.inputGetType(@ptrCast(element));
|
||||||
@@ -246,7 +246,7 @@ fn collectSelectValues(arena: Allocator, select: *parser.Select, name: []const u
|
|||||||
fn getSubmitterName(submitter_: ?*parser.ElementHTML) !?[]const u8 {
|
fn getSubmitterName(submitter_: ?*parser.ElementHTML) !?[]const u8 {
|
||||||
const submitter = submitter_ orelse return null;
|
const submitter = submitter_ orelse return null;
|
||||||
|
|
||||||
const tag = try parser.elementHTMLGetTagType(submitter);
|
const tag = try parser.elementTag(@ptrCast(submitter));
|
||||||
const element: *parser.Element = @ptrCast(submitter);
|
const element: *parser.Element = @ptrCast(submitter);
|
||||||
const name = try parser.elementGetAttribute(element, "name");
|
const name = try parser.elementGetAttribute(element, "name");
|
||||||
|
|
||||||
|
|||||||
2
vendor/netsurf/libdom
vendored
2
vendor/netsurf/libdom
vendored
Submodule vendor/netsurf/libdom updated: 11b5bf869a...16a0d91684
Reference in New Issue
Block a user