Add parser Tag

Signed-off-by: Francis Bouvier <francis.bouvier@gmail.com>
This commit is contained in:
Francis Bouvier
2023-05-18 16:32:42 +02:00
parent 98796d9512
commit 12b840b3d5
3 changed files with 226 additions and 245 deletions

View File

@@ -57,38 +57,6 @@ pub const HTMLDocument = struct {
// Tests
// -----
fn upper(comptime name: []const u8, comptime indexes: anytype) []u8 {
// indexes is [_]comptime_int
comptime {
var upper_name: [name.len]u8 = undefined;
for (name) |char, i| {
var toUpper = false;
for (indexes) |index| {
if (index == i) {
toUpper = true;
break;
}
}
if (toUpper) {
upper_name[i] = std.ascii.toUpper(char);
} else {
upper_name[i] = char;
}
}
return &upper_name;
}
}
// fn allUpper(comptime name: []const u8) []u8 {
// comptime {
// var upper_name: [name.len]u8 = undefined;
// for (name) |char, i| {
// upper_name[i] = std.ascii.toUpper(char);
// }
// return &upper_name;
// }
// }
pub fn testExecFn(
alloc: std.mem.Allocator,
js_env: *jsruntime.Env,
@@ -109,149 +77,29 @@ pub fn testExecFn(
};
try checkCases(js_env, &getElementById);
comptime var htmlElements = [_][]const u8{
"a", // Anchor
"area",
"audio",
"br", // BR
"base",
"body",
"button",
"canvas",
"dl", // DList
"dialog",
"data",
"div",
"embed",
"fieldset", // FieldSet
"form",
"frameset", // FrameSet
"hr", // HR
"head",
"h1", // Heading
"h2", // Heading
"h3", // Heading
"h4", // Heading
"h5", // Heading
"h6", // Heading
"html",
"iframe", // IFrame
"img", // Image
"input",
"li", // LI
"label",
"legend",
"link",
"map",
"meta",
"meter",
"ins", // Mod
"del", // Mod
"ol", // OList
"object",
"optgroup", // OptGroup
"option",
"output",
"p", // Paragraph
"picture",
"pre",
"progress",
"blockquote", // Quote
"q", // Quote
"script",
"select",
"source",
"span",
"style",
"table",
"caption", // TableCaption
"th", // TableCell
"td", // TableCell
"col", // TableCol
"tr", // TableRow
"thead", // TableSection
"tbody", // TableSection
"tfoot", // TableSection
"template",
"textarea", // TextArea
"time",
"title",
"track",
"ul", // UList
"video",
};
var createElement: [htmlElements.len * 3]Case = undefined;
inline for (htmlElements) |elem, i| {
var upperName: []const u8 = undefined;
if (std.mem.eql(u8, elem, "a")) {
upperName = "Anchor";
} else if (std.mem.eql(u8, elem, "dl")) {
upperName = "DList";
} else if (std.mem.eql(u8, elem, "fieldset")) {
upperName = "FieldSet";
} else if (std.mem.eql(u8, elem, "frameset")) {
upperName = "FrameSet";
} else if (std.mem.eql(u8, elem, "h1") or
std.mem.eql(u8, elem, "h2") or
std.mem.eql(u8, elem, "h3") or
std.mem.eql(u8, elem, "h4") or
std.mem.eql(u8, elem, "h5") or
std.mem.eql(u8, elem, "h6"))
{
upperName = "Heading";
} else if (std.mem.eql(u8, elem, "iframe")) {
upperName = "IFrame";
} else if (std.mem.eql(u8, elem, "img")) {
upperName = "Image";
} else if (std.mem.eql(u8, elem, "del") or std.mem.eql(u8, elem, "ins")) {
upperName = "Mod";
} else if (std.mem.eql(u8, elem, "ol")) {
upperName = "OList";
} else if (std.mem.eql(u8, elem, "optgroup")) {
upperName = "OptGroup";
} else if (std.mem.eql(u8, elem, "p")) {
upperName = "Paragraph";
} else if (std.mem.eql(u8, elem, "blockquote") or std.mem.eql(u8, elem, "q")) {
upperName = "Quote";
} else if (std.mem.eql(u8, elem, "caption")) {
upperName = "TableCaption";
} else if (std.mem.eql(u8, elem, "th") or std.mem.eql(u8, elem, "td")) {
upperName = "TableCell";
} else if (std.mem.eql(u8, elem, "col")) {
upperName = "TableCol";
} else if (std.mem.eql(u8, elem, "tr")) {
upperName = "TableRow";
} else if (std.mem.eql(u8, elem, "thead") or
std.mem.eql(u8, elem, "tbody") or
std.mem.eql(u8, elem, "tfoot"))
{
upperName = "TableSection";
} else if (std.mem.eql(u8, elem, "textarea")) {
upperName = "TextArea";
} else if (std.mem.eql(u8, elem, "ul")) {
upperName = "UList";
} else {
if (elem.len == 2) {
upperName = upper(elem, [_]comptime_int{ 0, 1 });
} else {
upperName = upper(elem, [_]comptime_int{0});
}
const tags = comptime parser.Tag.all();
const elements = comptime parser.Tag.allElements();
var createElements: [(tags.len - 1) * 3]Case = undefined;
inline for (tags) |tag, i| {
if (tag == .undef) {
continue;
}
createElement[i * 3] = Case{
.src = try std.fmt.allocPrint(alloc, "var {s}Elem = document.createElement('{s}')", .{ elem, elem }),
const tag_name = @tagName(tag);
const element_name = elements[i];
createElements[i * 3] = Case{
.src = try std.fmt.allocPrint(alloc, "var {s}Elem = document.createElement('{s}')", .{ tag_name, tag_name }),
.ex = "undefined",
};
createElement[(i * 3) + 1] = Case{
.src = try std.fmt.allocPrint(alloc, "{s}Elem.constructor.name", .{elem}),
.ex = try std.fmt.allocPrint(alloc, "HTML{s}Element", .{upperName}),
createElements[(i * 3) + 1] = Case{
.src = try std.fmt.allocPrint(alloc, "{s}Elem.constructor.name", .{tag_name}),
.ex = try std.fmt.allocPrint(alloc, "HTML{s}Element", .{element_name}),
};
createElement[(i * 3) + 2] = Case{
.src = try std.fmt.allocPrint(alloc, "{s}Elem.localName", .{elem}),
.ex = elem,
createElements[(i * 3) + 2] = Case{
.src = try std.fmt.allocPrint(alloc, "{s}Elem.localName", .{tag_name}),
.ex = tag_name,
};
}
try checkCases(js_env, &createElement);
try checkCases(js_env, &createElements);
var unknown = [_]Case{
.{ .src = "let unknown = document.createElement('unknown')", .ex = "undefined" },

View File

@@ -762,82 +762,68 @@ pub const HTMLVideoElement = struct {
}
};
const c = @cImport({
@cInclude("lexbor/html/html.h");
});
pub fn ElementToHTMLElementInterface(base: *parser.Element) HTMLElements {
return switch (base.*.node.local_name) {
c.LXB_TAG_A => .{ .anchor = HTMLAnchorElement.init(base) },
c.LXB_TAG_AREA => .{ .area = HTMLAreaElement.init(base) },
c.LXB_TAG_AUDIO => .{ .audio = HTMLAudioElement.init(base) },
c.LXB_TAG_BR => .{ .br = HTMLBRElement.init(base) },
c.LXB_TAG_BASE => .{ .base = HTMLBaseElement.init(base) },
c.LXB_TAG_BODY => .{ .body = HTMLBodyElement.init(base) },
c.LXB_TAG_BUTTON => .{ .button = HTMLButtonElement.init(base) },
c.LXB_TAG_CANVAS => .{ .canvas = HTMLCanvasElement.init(base) },
c.LXB_TAG_DL => .{ .dlist = HTMLDListElement.init(base) },
c.LXB_TAG_DIALOG => .{ .dialog = HTMLDialogElement.init(base) },
c.LXB_TAG_DATA => .{ .data = HTMLDataElement.init(base) },
c.LXB_TAG_DIV => .{ .div = HTMLDivElement.init(base) },
c.LXB_TAG_EMBED => .{ .embed = HTMLEmbedElement.init(base) },
c.LXB_TAG_FIELDSET => .{ .fieldset = HTMLFieldSetElement.init(base) },
c.LXB_TAG_FORM => .{ .form = HTMLFormElement.init(base) },
c.LXB_TAG_FRAMESET => .{ .frameset = HTMLFrameSetElement.init(base) },
c.LXB_TAG_HR => .{ .hr = HTMLHRElement.init(base) },
c.LXB_TAG_HEAD => .{ .head = HTMLHeadElement.init(base) },
c.LXB_TAG_H1 => .{ .heading = HTMLHeadingElement.init(base) },
c.LXB_TAG_H2 => .{ .heading = HTMLHeadingElement.init(base) },
c.LXB_TAG_H3 => .{ .heading = HTMLHeadingElement.init(base) },
c.LXB_TAG_H4 => .{ .heading = HTMLHeadingElement.init(base) },
c.LXB_TAG_H5 => .{ .heading = HTMLHeadingElement.init(base) },
c.LXB_TAG_H6 => .{ .heading = HTMLHeadingElement.init(base) },
c.LXB_TAG_HTML => .{ .html = HTMLHtmlElement.init(base) },
c.LXB_TAG_IFRAME => .{ .iframe = HTMLIFrameElement.init(base) },
c.LXB_TAG_IMG => .{ .img = HTMLImageElement.init(base) },
c.LXB_TAG_INPUT => .{ .input = HTMLInputElement.init(base) },
c.LXB_TAG_LI => .{ .li = HTMLLIElement.init(base) },
c.LXB_TAG_LABEL => .{ .label = HTMLLabelElement.init(base) },
c.LXB_TAG_LEGEND => .{ .legend = HTMLLegendElement.init(base) },
c.LXB_TAG_LINK => .{ .link = HTMLLinkElement.init(base) },
c.LXB_TAG_MAP => .{ .map = HTMLMapElement.init(base) },
c.LXB_TAG_META => .{ .meta = HTMLMetaElement.init(base) },
c.LXB_TAG_METER => .{ .meter = HTMLMeterElement.init(base) },
c.LXB_TAG_INS => .{ .mod = HTMLModElement.init(base) },
c.LXB_TAG_DEL => .{ .mod = HTMLModElement.init(base) },
c.LXB_TAG_OL => .{ .olist = HTMLOListElement.init(base) },
c.LXB_TAG_OBJECT => .{ .object = HTMLObjectElement.init(base) },
c.LXB_TAG_OPTGROUP => .{ .optgroup = HTMLOptGroupElement.init(base) },
c.LXB_TAG_OPTION => .{ .option = HTMLOptionElement.init(base) },
c.LXB_TAG_OUTPUT => .{ .output = HTMLOutputElement.init(base) },
c.LXB_TAG_P => .{ .paragraph = HTMLParagraphElement.init(base) },
c.LXB_TAG_PICTURE => .{ .picture = HTMLPictureElement.init(base) },
c.LXB_TAG_PRE => .{ .pre = HTMLPreElement.init(base) },
c.LXB_TAG_PROGRESS => .{ .progress = HTMLProgressElement.init(base) },
c.LXB_TAG_BLOCKQUOTE => .{ .quote = HTMLQuoteElement.init(base) },
c.LXB_TAG_Q => .{ .quote = HTMLQuoteElement.init(base) },
c.LXB_TAG_SCRIPT => .{ .script = HTMLScriptElement.init(base) },
c.LXB_TAG_SELECT => .{ .select = HTMLSelectElement.init(base) },
c.LXB_TAG_SOURCE => .{ .source = HTMLSourceElement.init(base) },
c.LXB_TAG_SPAN => .{ .span = HTMLSpanElement.init(base) },
c.LXB_TAG_STYLE => .{ .style = HTMLStyleElement.init(base) },
c.LXB_TAG_TABLE => .{ .table = HTMLTableElement.init(base) },
c.LXB_TAG_CAPTION => .{ .tablecaption = HTMLTableCaptionElement.init(base) },
c.LXB_TAG_TH => .{ .tablecell = HTMLTableCellElement.init(base) },
c.LXB_TAG_TD => .{ .tablecell = HTMLTableCellElement.init(base) },
c.LXB_TAG_COL => .{ .tablecol = HTMLTableColElement.init(base) },
c.LXB_TAG_TR => .{ .tablerow = HTMLTableRowElement.init(base) },
c.LXB_TAG_THEAD => .{ .tablesection = HTMLTableSectionElement.init(base) },
c.LXB_TAG_TBODY => .{ .tablesection = HTMLTableSectionElement.init(base) },
c.LXB_TAG_TFOOT => .{ .tablesection = HTMLTableSectionElement.init(base) },
c.LXB_TAG_TEMPLATE => .{ .template = HTMLTemplateElement.init(base) },
c.LXB_TAG_TEXTAREA => .{ .textarea = HTMLTextAreaElement.init(base) },
c.LXB_TAG_TIME => .{ .time = HTMLTimeElement.init(base) },
c.LXB_TAG_TITLE => .{ .title = HTMLTitleElement.init(base) },
c.LXB_TAG_TRACK => .{ .track = HTMLTrackElement.init(base) },
c.LXB_TAG_UL => .{ .ulist = HTMLUListElement.init(base) },
c.LXB_TAG_VIDEO => .{ .video = HTMLVideoElement.init(base) },
c.LXB_TAG__UNDEF => .{ .unknown = HTMLUnknownElement.init(base) },
else => .{ .unknown = HTMLUnknownElement.init(base) },
const tag = parser.nodeTag(parser.elementNode(base));
return switch (tag) {
.a => .{ .anchor = HTMLAnchorElement.init(base) },
.area => .{ .area = HTMLAreaElement.init(base) },
.audio => .{ .audio = HTMLAudioElement.init(base) },
.br => .{ .br = HTMLBRElement.init(base) },
.base => .{ .base = HTMLBaseElement.init(base) },
.body => .{ .body = HTMLBodyElement.init(base) },
.button => .{ .button = HTMLButtonElement.init(base) },
.canvas => .{ .canvas = HTMLCanvasElement.init(base) },
.dl => .{ .dlist = HTMLDListElement.init(base) },
.dialog => .{ .dialog = HTMLDialogElement.init(base) },
.data => .{ .data = HTMLDataElement.init(base) },
.div => .{ .div = HTMLDivElement.init(base) },
.embed => .{ .embed = HTMLEmbedElement.init(base) },
.fieldset => .{ .fieldset = HTMLFieldSetElement.init(base) },
.form => .{ .form = HTMLFormElement.init(base) },
.frameset => .{ .frameset = HTMLFrameSetElement.init(base) },
.hr => .{ .hr = HTMLHRElement.init(base) },
.head => .{ .head = HTMLHeadElement.init(base) },
.h1, .h2, .h3, .h4, .h5, .h6 => .{ .heading = HTMLHeadingElement.init(base) },
.html => .{ .html = HTMLHtmlElement.init(base) },
.iframe => .{ .iframe = HTMLIFrameElement.init(base) },
.img => .{ .img = HTMLImageElement.init(base) },
.input => .{ .input = HTMLInputElement.init(base) },
.li => .{ .li = HTMLLIElement.init(base) },
.label => .{ .label = HTMLLabelElement.init(base) },
.legend => .{ .legend = HTMLLegendElement.init(base) },
.link => .{ .link = HTMLLinkElement.init(base) },
.map => .{ .map = HTMLMapElement.init(base) },
.meta => .{ .meta = HTMLMetaElement.init(base) },
.meter => .{ .meter = HTMLMeterElement.init(base) },
.ins, .del => .{ .mod = HTMLModElement.init(base) },
.ol => .{ .olist = HTMLOListElement.init(base) },
.object => .{ .object = HTMLObjectElement.init(base) },
.optgroup => .{ .optgroup = HTMLOptGroupElement.init(base) },
.option => .{ .option = HTMLOptionElement.init(base) },
.output => .{ .output = HTMLOutputElement.init(base) },
.p => .{ .paragraph = HTMLParagraphElement.init(base) },
.picture => .{ .picture = HTMLPictureElement.init(base) },
.pre => .{ .pre = HTMLPreElement.init(base) },
.progress => .{ .progress = HTMLProgressElement.init(base) },
.blockquote, .q => .{ .quote = HTMLQuoteElement.init(base) },
.script => .{ .script = HTMLScriptElement.init(base) },
.select => .{ .select = HTMLSelectElement.init(base) },
.source => .{ .source = HTMLSourceElement.init(base) },
.span => .{ .span = HTMLSpanElement.init(base) },
.style => .{ .style = HTMLStyleElement.init(base) },
.table => .{ .table = HTMLTableElement.init(base) },
.caption => .{ .tablecaption = HTMLTableCaptionElement.init(base) },
.th, .td => .{ .tablecell = HTMLTableCellElement.init(base) },
.col => .{ .tablecol = HTMLTableColElement.init(base) },
.tr => .{ .tablerow = HTMLTableRowElement.init(base) },
.thead, .tbody, .tfoot => .{ .tablesection = HTMLTableSectionElement.init(base) },
.template => .{ .template = HTMLTemplateElement.init(base) },
.textarea => .{ .textarea = HTMLTextAreaElement.init(base) },
.time => .{ .time = HTMLTimeElement.init(base) },
.title => .{ .title = HTMLTitleElement.init(base) },
.track => .{ .track = HTMLTrackElement.init(base) },
.ul => .{ .ulist = HTMLUListElement.init(base) },
.video => .{ .video = HTMLVideoElement.init(base) },
.undef => .{ .unknown = HTMLUnknownElement.init(base) },
};
}