aboutsummaryrefslogtreecommitdiff
path: root/src/dom
diff options
context:
space:
mode:
authorAnhgelus Morhtuuzh <william@herges.fr>2026-04-16 23:05:14 +0200
committerAnhgelus Morhtuuzh <william@herges.fr>2026-04-16 23:05:14 +0200
commit6a7d7758e0a4b0b1989a7fbddd5424c811cd5e8a (patch)
treebb4f9d575223659aeec70cf86092b9fad382034a /src/dom
parent6df64050b1442a5f3a0f566cd816639ac1fd298f (diff)
feat(dom): init for common tags
Diffstat (limited to 'src/dom')
-rw-r--r--src/dom/Element.zig73
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 = &in;
+ 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>");
}