diff options
| author | Anhgelus Morhtuuzh <william@herges.fr> | 2026-04-16 23:05:14 +0200 |
|---|---|---|
| committer | Anhgelus Morhtuuzh <william@herges.fr> | 2026-04-16 23:05:14 +0200 |
| commit | 6a7d7758e0a4b0b1989a7fbddd5424c811cd5e8a (patch) | |
| tree | bb4f9d575223659aeec70cf86092b9fad382034a /src/dom | |
| parent | 6df64050b1442a5f3a0f566cd816639ac1fd298f (diff) | |
feat(dom): init for common tags
Diffstat (limited to 'src/dom')
| -rw-r--r-- | src/dom/Element.zig | 73 |
1 files changed, 56 insertions, 17 deletions
diff --git a/src/dom/Element.zig b/src/dom/Element.zig index ff8a3d1..5b6c685 100644 --- a/src/dom/Element.zig +++ b/src/dom/Element.zig @@ -11,15 +11,17 @@ pub const Kind = enum { const Self = @This(); kind: Kind, +alloc: Allocator, tag: ?[]const u8 = null, attributes: std.StringArrayHashMap([]const u8), class_list: std.BufSet, -content: ?[]*Self = null, +content: std.ArrayList(Self) = .empty, literal: ?[]const u8 = null, pub fn init(alloc: Allocator, knd: Kind, tag: []const u8) Self { return .{ .kind = knd, + .alloc = alloc, .tag = tag, .attributes = .init(alloc), .class_list = .init(alloc), @@ -27,15 +29,26 @@ pub fn init(alloc: Allocator, knd: Kind, tag: []const u8) Self { } pub fn initLit(alloc: Allocator, literal: []const u8) Self { - return .{ .kind = .literal, .literal = literal, .attributes = .init(alloc), .class_list = .init(alloc) }; + return .{ + .kind = .literal, + .alloc = alloc, + .literal = literal, + .attributes = .init(alloc), + .class_list = .init(alloc), + }; } pub fn deinit(self: *Self) void { self.attributes.deinit(); self.class_list.deinit(); + for (self.content.items) |it| { + var v = it; + v.deinit(); + } + self.content.deinit(self.alloc); } -pub fn render(self: *Self, alloc: Allocator) !std.ArrayList(u8) { +pub fn render(self: *const Self, alloc: Allocator) !std.ArrayList(u8) { var attr = try self.renderAttribute(alloc); defer attr.deinit(alloc); var acc = try std.ArrayList(u8).initCapacity(alloc, 2); @@ -49,12 +62,10 @@ pub fn render(self: *Self, alloc: Allocator) !std.ArrayList(u8) { switch (self.kind) { .void => return acc, .content => { - if (self.content) |content| { - for (content) |it| { - var sub = try it.render(alloc); - defer sub.deinit(alloc); - try acc.appendSlice(alloc, sub.items); - } + for (self.content.items) |it| { + var sub = try it.render(alloc); + defer sub.deinit(alloc); + try acc.appendSlice(alloc, sub.items); } }, .literal => try acc.appendSlice(alloc, self.literal.?), @@ -67,7 +78,7 @@ pub fn render(self: *Self, alloc: Allocator) !std.ArrayList(u8) { return acc; } -fn renderAttribute(self: *Self, alloc: Allocator) !std.ArrayList(u8) { +fn renderAttribute(self: *const Self, alloc: Allocator) !std.ArrayList(u8) { var iter = self.attributes.iterator(); if (iter.len == 0) return .empty; var acc = try std.ArrayList(u8).initCapacity(alloc, 2); @@ -97,6 +108,29 @@ pub fn hasAttribute(self: *Self, k: []const u8) bool { return self.attributes.contains(k); } +pub fn appendContent(self: *Self, content: Self) !void { + return self.content.append(self.alloc, content); +} + +pub fn initImg(alloc: Allocator, src: []const u8, alt: []const u8) !Self { + var el = init(alloc, .void, "img"); + try el.setAttribute("src", src); + try el.setAttribute("alt", alt); + return el; +} + +pub fn initContent(alloc: Allocator, tag: []const u8, content: []Self) !Self { + var el = init(alloc, .content, tag); + for (content) |it| try el.appendContent(it); + return el; +} + +pub fn initParagraph(alloc: Allocator, content: []const u8) !Self { + var el = init(alloc, .content, "p"); + try el.appendContent(initLit(alloc, content)); + return el; +} + fn doTest(alloc: Allocator, el: *Self, exp: []const u8) !void { var rendered = try el.render(alloc); defer rendered.deinit(alloc); @@ -122,6 +156,10 @@ test "void element" { try img.setAttribute("alt", "bar"); try doTest(alloc, &img, "<img src=\"foo\" alt=\"bar\">"); + + var img2 = try initImg(alloc, "foo", "bar"); + defer img2.deinit(); + try doTest(alloc, &img2, "<img src=\"foo\" alt=\"bar\">"); } test "content element" { @@ -133,18 +171,19 @@ test "content element" { defer p.deinit(); var content = initLit(alloc, "hello world"); - defer content.deinit(); - var in = [_]*Self{&content}; - p.content = ∈ + try p.appendContent(content); try doTest(alloc, &content, "hello world"); try doTest(alloc, &p, "<p>hello world</p>"); + var p_managed = try initParagraph(alloc, "hello world"); + defer p_managed.deinit(); + try doTest(alloc, &p_managed, "<p>hello world</p>"); + var div = init(alloc, .content, "div"); defer div.deinit(); try div.setAttribute("class", "foo-bar"); - var in2 = [_]*Self{&p, &content}; - div.content = &in2; - - try doTest(alloc, &div, "<div class=\"foo-bar\"><p>hello world</p>hello world</div>"); + try div.appendContent(try initParagraph(alloc, "hello world")); + try div.appendContent(try initImg(alloc, "example.org", "example")); + try doTest(alloc, &div, "<div class=\"foo-bar\"><p>hello world</p><img src=\"example.org\" alt=\"example\"></div>"); } |
