aboutsummaryrefslogtreecommitdiff
path: root/src/eval/html/Element.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/eval/html/Element.zig')
-rw-r--r--src/eval/html/Element.zig55
1 files changed, 31 insertions, 24 deletions
diff --git a/src/eval/html/Element.zig b/src/eval/html/Element.zig
index 6bccc0f..6073e6a 100644
--- a/src/eval/html/Element.zig
+++ b/src/eval/html/Element.zig
@@ -2,28 +2,47 @@ const std = @import("std");
const Arena = std.heap.ArenaAllocator;
const Allocator = std.mem.Allocator;
const eql = std.mem.eql;
-const List = std.ArrayList;
const html = @import("html.zig");
pub const Void = @import("Void.zig");
-pub const Content = @import("Content.zig");
+pub const Content = @import("Content.zig");
pub const Literal = @import("Literal.zig");
pub const Root = @import("Root.zig");
pub const Error = html.Error || Allocator.Error;
-const Element = @This();
+pub const Node = struct {
+ ptr: *anyopaque,
+ vtable: struct { element: *const fn (*anyopaque) Self },
+ node: std.DoublyLinkedList.Node = .{},
+
+ pub fn from(n: *std.DoublyLinkedList.Node) *Node {
+ const v: *Node = @fieldParentPtr("node", n);
+ return v;
+ }
+
+ pub fn element(self: Node) Self {
+ return self.vtable.element(self.ptr);
+ }
+};
+
+const Self = @This();
vtable: struct {
render: *const fn (self: *anyopaque, alloc: Allocator) Error![]const u8,
+ node: *const fn (self: *anyopaque) *Node,
},
ptr: *anyopaque,
-pub fn render(self: Element, alloc: Allocator) Error![]const u8 {
+pub fn render(self: Self, alloc: Allocator) Error![]const u8 {
return self.vtable.render(self.ptr, alloc);
}
-fn doTest(alloc: Allocator, el: Element, exp: []const u8) !void {
+pub fn node(self: Self) *Node {
+ return self.vtable.node(self.ptr);
+}
+
+fn doTest(alloc: Allocator, el: Self, exp: []const u8) !void {
const got = try el.render(alloc);
defer alloc.free(got);
std.testing.expect(eql(u8, got, exp)) catch |err| {
@@ -54,33 +73,21 @@ test "content" {
const alloc = arena.allocator();
var p = try Content.init(alloc, "p");
+ var root = try Root.init(alloc);
+ p.content = root.element();
var content = try Literal.init(alloc, "hello world");
- try p.append(content.element());
+ root.append(content.element());
try doTest(alloc, content.element(), "hello world");
try doTest(alloc, p.element(), "<p>hello world</p>");
var div = try Content.init(alloc, "div");
+ var rootDiv = try Root.init(alloc);
+ div.content = rootDiv.element();
try div.base.appendClass("foo-bar");
- try div.append(p.element());
- try div.append((try Void.init(alloc, "br")).element());
+ rootDiv.append(p.element());
+ rootDiv.append((try Void.init(alloc, "br")).element());
try doTest(alloc, div.element(), "<div class=\"foo-bar\"><p>hello world</p><br></div>");
}
-
-test "root" {
- const root = try Root.init(std.testing.allocator);
- defer root.deinit();
- const alloc = root.allocator();
-
- var p = try Content.init(alloc, "p");
- var content = try Literal.init(alloc, "hello world");
- try p.append(content.element());
- try root.append(p.element());
-
- var br = try Void.init(alloc, "br");
- try root.append(br.element());
-
- try doTest(alloc, root.element(), "<p>hello world</p><br>");
-}