diff --git a/src/dom/document.zig b/src/dom/document.zig index 0b8d0cd8c..541a4d403 100644 --- a/src/dom/document.zig +++ b/src/dom/document.zig @@ -145,18 +145,18 @@ pub const Document = struct { // HTMLCollection in zig here. pub fn _getElementsByTagName( self: *parser.Document, - alloc: std.mem.Allocator, + arena: std.mem.Allocator, tag_name: []const u8, ) !collection.HTMLCollection { - return try collection.HTMLCollectionByTagName(alloc, parser.documentToNode(self), tag_name, true); + return try collection.HTMLCollectionByTagName(arena, parser.documentToNode(self), tag_name, true); } pub fn _getElementsByClassName( self: *parser.Document, - alloc: std.mem.Allocator, + arena: std.mem.Allocator, classNames: []const u8, ) !collection.HTMLCollection { - return try collection.HTMLCollectionByClassName(alloc, parser.documentToNode(self), classNames, true); + return try collection.HTMLCollectionByClassName(arena, parser.documentToNode(self), classNames, true); } pub fn _createDocumentFragment(self: *parser.Document) !*parser.DocumentFragment { @@ -218,18 +218,18 @@ pub const Document = struct { return 1; } - pub fn _querySelector(self: *parser.Document, alloc: std.mem.Allocator, selector: []const u8) !?ElementUnion { + pub fn _querySelector(self: *parser.Document, arena: std.mem.Allocator, selector: []const u8) !?ElementUnion { if (selector.len == 0) return null; - const n = try css.querySelector(alloc, parser.documentToNode(self), selector); + const n = try css.querySelector(arena, parser.documentToNode(self), selector); if (n == null) return null; return try Element.toInterface(parser.nodeToElement(n.?)); } - pub fn _querySelectorAll(self: *parser.Document, alloc: std.mem.Allocator, selector: []const u8) !NodeList { - return css.querySelectorAll(alloc, parser.documentToNode(self), selector); + pub fn _querySelectorAll(self: *parser.Document, arena: std.mem.Allocator, selector: []const u8) !NodeList { + return css.querySelectorAll(arena, parser.documentToNode(self), selector); } // TODO according with https://dom.spec.whatwg.org/#parentnode, the diff --git a/src/dom/element.zig b/src/dom/element.zig index 0453a283a..8d88b5248 100644 --- a/src/dom/element.zig +++ b/src/dom/element.zig @@ -106,24 +106,16 @@ pub const Element = struct { return try parser.nodeGetAttributes(parser.elementToNode(self)); } - pub fn get_innerHTML(self: *parser.Element, alloc: std.mem.Allocator) ![]const u8 { - var buf = std.ArrayList(u8).init(alloc); - defer buf.deinit(); - + pub fn get_innerHTML(self: *parser.Element, arena: std.mem.Allocator) ![]const u8 { + var buf = std.ArrayList(u8).init(arena); try dump.writeChildren(parser.elementToNode(self), buf.writer()); - // TODO express the caller owned the slice. - // https://github.com/lightpanda-io/jsruntime-lib/issues/195 - return buf.toOwnedSlice(); + return buf.items; } - pub fn get_outerHTML(self: *parser.Element, alloc: std.mem.Allocator) ![]const u8 { - var buf = std.ArrayList(u8).init(alloc); - defer buf.deinit(); - + pub fn get_outerHTML(self: *parser.Element, arena: std.mem.Allocator) ![]const u8 { + var buf = std.ArrayList(u8).init(arena); try dump.writeNode(parser.elementToNode(self), buf.writer()); - // TODO express the caller owned the slice. - // https://github.com/lightpanda-io/jsruntime-lib/issues/195 - return buf.toOwnedSlice(); + return buf.items; } pub fn set_innerHTML(self: *parser.Element, str: []const u8) !void { @@ -232,11 +224,11 @@ pub const Element = struct { pub fn _getElementsByTagName( self: *parser.Element, - alloc: std.mem.Allocator, + arena: std.mem.Allocator, tag_name: []const u8, ) !collection.HTMLCollection { return try collection.HTMLCollectionByTagName( - alloc, + arena, parser.elementToNode(self), tag_name, false, @@ -245,11 +237,11 @@ pub const Element = struct { pub fn _getElementsByClassName( self: *parser.Element, - alloc: std.mem.Allocator, + arena: std.mem.Allocator, classNames: []const u8, ) !collection.HTMLCollection { return try collection.HTMLCollectionByClassName( - alloc, + arena, parser.elementToNode(self), classNames, false, @@ -312,18 +304,18 @@ pub const Element = struct { } } - pub fn _querySelector(self: *parser.Element, alloc: std.mem.Allocator, selector: []const u8) !?Union { + pub fn _querySelector(self: *parser.Element, arena: std.mem.Allocator, selector: []const u8) !?Union { if (selector.len == 0) return null; - const n = try css.querySelector(alloc, parser.elementToNode(self), selector); + const n = try css.querySelector(arena, parser.elementToNode(self), selector); if (n == null) return null; return try toInterface(parser.nodeToElement(n.?)); } - pub fn _querySelectorAll(self: *parser.Element, alloc: std.mem.Allocator, selector: []const u8) !NodeList { - return css.querySelectorAll(alloc, parser.elementToNode(self), selector); + pub fn _querySelectorAll(self: *parser.Element, arena: std.mem.Allocator, selector: []const u8) !NodeList { + return css.querySelectorAll(arena, parser.elementToNode(self), selector); } // TODO according with https://dom.spec.whatwg.org/#parentnode, the diff --git a/src/dom/exceptions.zig b/src/dom/exceptions.zig index 209f4345d..b80d77131 100644 --- a/src/dom/exceptions.zig +++ b/src/dom/exceptions.zig @@ -61,19 +61,18 @@ pub const DOMException = struct { pub const _INVALID_NODE_TYPE_ERR = 24; pub const _DATA_CLONE_ERR = 25; - // TODO: deinit - pub fn init(alloc: std.mem.Allocator, err: anyerror, callerName: []const u8) anyerror!DOMException { + pub fn init(arena: std.mem.Allocator, err: anyerror, callerName: []const u8) anyerror!DOMException { const errCast = @as(parser.DOMError, @errorCast(err)); const errName = DOMException.name(errCast); const str = switch (errCast) { error.HierarchyRequest => try allocPrint( - alloc, + arena, "{s}: Failed to execute '{s}' on 'Node': The new child element contains the parent.", .{ errName, callerName }, ), error.NoError => unreachable, else => try allocPrint( - alloc, + arena, "{s}: TODO message", // TODO: implement other messages .{DOMException.name(errCast)}, ), diff --git a/src/dom/implementation.zig b/src/dom/implementation.zig index ec90014f2..259aed2cd 100644 --- a/src/dom/implementation.zig +++ b/src/dom/implementation.zig @@ -36,41 +36,34 @@ pub const DOMImplementation = struct { pub fn _createDocumentType( _: *DOMImplementation, - alloc: std.mem.Allocator, + arena: std.mem.Allocator, qname: []const u8, publicId: []const u8, systemId: []const u8, ) !*parser.DocumentType { - const cqname = try alloc.dupeZ(u8, qname); - defer alloc.free(cqname); - - const cpublicId = try alloc.dupeZ(u8, publicId); - defer alloc.free(cpublicId); - - const csystemId = try alloc.dupeZ(u8, systemId); - defer alloc.free(csystemId); + const cqname = try arena.dupeZ(u8, qname); + const cpublicId = try arena.dupeZ(u8, publicId); + const csystemId = try arena.dupeZ(u8, systemId); return try parser.domImplementationCreateDocumentType(cqname, cpublicId, csystemId); } pub fn _createDocument( _: *DOMImplementation, - alloc: std.mem.Allocator, + arena: std.mem.Allocator, namespace: ?[]const u8, qname: ?[]const u8, doctype: ?*parser.DocumentType, ) !*parser.Document { var cnamespace: ?[:0]const u8 = null; if (namespace) |ns| { - cnamespace = try alloc.dupeZ(u8, ns); + cnamespace = try arena.dupeZ(u8, ns); } - defer if (cnamespace) |v| alloc.free(v); var cqname: ?[:0]const u8 = null; if (qname) |qn| { - cqname = try alloc.dupeZ(u8, qn); + cqname = try arena.dupeZ(u8, qn); } - defer if (cqname) |v| alloc.free(v); return try parser.domImplementationCreateDocument(cnamespace, cqname, doctype); } diff --git a/src/dom/node.zig b/src/dom/node.zig index 3e0a75610..1d1b6d7a4 100644 --- a/src/dom/node.zig +++ b/src/dom/node.zig @@ -262,13 +262,12 @@ pub const Node = struct { return try parser.nodeHasChildNodes(self); } - pub fn get_childNodes(self: *parser.Node, alloc: std.mem.Allocator) !NodeList { + pub fn get_childNodes(self: *parser.Node, arena: std.mem.Allocator) !NodeList { var list = NodeList.init(); - errdefer list.deinit(alloc); var n = try parser.nodeFirstChild(self) orelse return list; while (true) { - try list.append(alloc, n); + try list.append(arena, n); n = try parser.nodeNextSibling(n) orelse return list; } } diff --git a/src/dom/nodelist.zig b/src/dom/nodelist.zig index 5dfc70310..26537453c 100644 --- a/src/dom/nodelist.zig +++ b/src/dom/nodelist.zig @@ -122,8 +122,8 @@ pub const NodeList = struct { self.nodes.deinit(alloc); } - pub fn append(self: *NodeList, alloc: std.mem.Allocator, node: *parser.Node) !void { - try self.nodes.append(alloc, node); + pub fn append(self: *NodeList, arena: std.mem.Allocator, node: *parser.Node) !void { + try self.nodes.append(arena, node); } pub fn get_length(self: *NodeList) u32 { @@ -139,9 +139,8 @@ pub const NodeList = struct { return try Node.toInterface(n); } - pub fn _forEach(self: *NodeList, alloc: std.mem.Allocator, cbk: Callback) !void { // TODO handle thisArg - var res = CallbackResult.init(alloc); - defer res.deinit(); + pub fn _forEach(self: *NodeList, arena: std.mem.Allocator, cbk: Callback) !void { // TODO handle thisArg + var res = CallbackResult.init(arena); for (self.nodes.items, 0..) |n, i| { const ii: u32 = @intCast(i); @@ -172,12 +171,12 @@ pub const NodeList = struct { // TODO entries() https://developer.mozilla.org/en-US/docs/Web/API/NodeList/entries - pub fn postAttach(self: *NodeList, alloc: std.mem.Allocator, js_obj: jsruntime.JSObject) !void { + pub fn postAttach(self: *NodeList, arena: std.mem.Allocator, js_obj: jsruntime.JSObject) !void { const ln = self.get_length(); var i: u32 = 0; while (i < ln) { defer i += 1; - const k = try std.fmt.allocPrint(alloc, "{d}", .{i}); + const k = try std.fmt.allocPrint(arena, "{d}", .{i}); const node = try self._item(i) orelse unreachable; try js_obj.set(k, node); diff --git a/src/html/document.zig b/src/html/document.zig index 11d16c3ef..6a1f2c437 100644 --- a/src/html/document.zig +++ b/src/html/document.zig @@ -100,44 +100,43 @@ pub const HTMLDocument = struct { return v; } - pub fn _getElementsByName(self: *parser.DocumentHTML, alloc: std.mem.Allocator, name: []const u8) !NodeList { + pub fn _getElementsByName(self: *parser.DocumentHTML, arena: std.mem.Allocator, name: []const u8) !NodeList { var list = NodeList.init(); - errdefer list.deinit(alloc); if (name.len == 0) return list; const root = parser.documentHTMLToNode(self); - var c = try collection.HTMLCollectionByName(alloc, root, name, false); + var c = try collection.HTMLCollectionByName(arena, root, name, false); const ln = try c.get_length(); var i: u32 = 0; while (i < ln) { const n = try c.item(i) orelse break; - try list.append(alloc, n); + try list.append(arena, n); i += 1; } return list; } - pub fn get_images(self: *parser.DocumentHTML, alloc: std.mem.Allocator) !collection.HTMLCollection { - return try collection.HTMLCollectionByTagName(alloc, parser.documentHTMLToNode(self), "img", false); + pub fn get_images(self: *parser.DocumentHTML, arena: std.mem.Allocator) !collection.HTMLCollection { + return try collection.HTMLCollectionByTagName(arena, parser.documentHTMLToNode(self), "img", false); } - pub fn get_embeds(self: *parser.DocumentHTML, alloc: std.mem.Allocator) !collection.HTMLCollection { - return try collection.HTMLCollectionByTagName(alloc, parser.documentHTMLToNode(self), "embed", false); + pub fn get_embeds(self: *parser.DocumentHTML, arena: std.mem.Allocator) !collection.HTMLCollection { + return try collection.HTMLCollectionByTagName(arena, parser.documentHTMLToNode(self), "embed", false); } - pub fn get_plugins(self: *parser.DocumentHTML, alloc: std.mem.Allocator) !collection.HTMLCollection { - return get_embeds(self, alloc); + pub fn get_plugins(self: *parser.DocumentHTML, arena: std.mem.Allocator) !collection.HTMLCollection { + return get_embeds(self, arena); } - pub fn get_forms(self: *parser.DocumentHTML, alloc: std.mem.Allocator) !collection.HTMLCollection { - return try collection.HTMLCollectionByTagName(alloc, parser.documentHTMLToNode(self), "form", false); + pub fn get_forms(self: *parser.DocumentHTML, arena: std.mem.Allocator) !collection.HTMLCollection { + return try collection.HTMLCollectionByTagName(arena, parser.documentHTMLToNode(self), "form", false); } - pub fn get_scripts(self: *parser.DocumentHTML, alloc: std.mem.Allocator) !collection.HTMLCollection { - return try collection.HTMLCollectionByTagName(alloc, parser.documentHTMLToNode(self), "script", false); + pub fn get_scripts(self: *parser.DocumentHTML, arena: std.mem.Allocator) !collection.HTMLCollection { + return try collection.HTMLCollectionByTagName(arena, parser.documentHTMLToNode(self), "script", false); } pub fn get_applets(_: *parser.DocumentHTML) !collection.HTMLCollection { diff --git a/src/html/elements.zig b/src/html/elements.zig index d0ff13a4c..c3590823e 100644 --- a/src/html/elements.zig +++ b/src/html/elements.zig @@ -218,47 +218,34 @@ pub const HTMLAnchorElement = struct { return try parser.nodeSetTextContent(parser.anchorToNode(self), v); } - inline fn url(self: *parser.Anchor, alloc: std.mem.Allocator) !URL { + inline fn url(self: *parser.Anchor, arena: std.mem.Allocator) !URL { const href = try parser.anchorGetHref(self); - return URL.constructor(alloc, href, null); // TODO inject base url + return URL.constructor(arena, href, null); // TODO inject base url } - // TODO return a disposable string - pub fn get_origin(self: *parser.Anchor, alloc: std.mem.Allocator) ![]const u8 { - var u = try url(self, alloc); - defer u.deinit(alloc); - - return try u.get_origin(alloc); + pub fn get_origin(self: *parser.Anchor, arena: std.mem.Allocator) ![]const u8 { + var u = try url(self, arena); + return try u.get_origin(arena); } - // TODO return a disposable string - pub fn get_protocol(self: *parser.Anchor, alloc: std.mem.Allocator) ![]const u8 { - var u = try url(self, alloc); - defer u.deinit(alloc); - - return u.get_protocol(alloc); + pub fn get_protocol(self: *parser.Anchor, arena: std.mem.Allocator) ![]const u8 { + var u = try url(self, arena); + return u.get_protocol(arena); } - pub fn set_protocol(self: *parser.Anchor, alloc: std.mem.Allocator, v: []const u8) !void { - var u = try url(self, alloc); - defer u.deinit(alloc); - + pub fn set_protocol(self: *parser.Anchor, arena: std.mem.Allocator, v: []const u8) !void { + var u = try url(self, arena); u.uri.scheme = v; - const href = try u.format(alloc); - defer alloc.free(href); - + const href = try u.format(arena); try parser.anchorSetHref(self, href); } - // TODO return a disposable string - pub fn get_host(self: *parser.Anchor, alloc: std.mem.Allocator) ![]const u8 { - var u = try url(self, alloc); - defer u.deinit(alloc); - - return try u.get_host(alloc); + pub fn get_host(self: *parser.Anchor, arena: std.mem.Allocator) ![]const u8 { + var u = try url(self, arena); + return try u.get_host(arena); } - pub fn set_host(self: *parser.Anchor, alloc: std.mem.Allocator, v: []const u8) !void { + pub fn set_host(self: *parser.Anchor, arena: std.mem.Allocator, v: []const u8) !void { // search : separator var p: ?u16 = null; var h: []const u8 = undefined; @@ -270,9 +257,7 @@ pub const HTMLAnchorElement = struct { } } - var u = try url(self, alloc); - defer u.deinit(alloc); - + var u = try url(self, arena); if (p) |pp| { u.uri.host = .{ .raw = h }; u.uri.port = pp; @@ -281,160 +266,118 @@ pub const HTMLAnchorElement = struct { u.uri.port = null; } - const href = try u.format(alloc); - defer alloc.free(href); - + const href = try u.format(arena); try parser.anchorSetHref(self, href); } - // TODO return a disposable string - pub fn get_hostname(self: *parser.Anchor, alloc: std.mem.Allocator) ![]const u8 { - var u = try url(self, alloc); - defer u.deinit(alloc); - - return try alloc.dupe(u8, u.get_hostname()); + pub fn get_hostname(self: *parser.Anchor, arena: std.mem.Allocator) ![]const u8 { + var u = try url(self, arena); + return try arena.dupe(u8, u.get_hostname()); } - pub fn set_hostname(self: *parser.Anchor, alloc: std.mem.Allocator, v: []const u8) !void { - var u = try url(self, alloc); - defer u.deinit(alloc); - + pub fn set_hostname(self: *parser.Anchor, arena: std.mem.Allocator, v: []const u8) !void { + var u = try url(self, arena); u.uri.host = .{ .raw = v }; - const href = try u.format(alloc); + const href = try u.format(arena); try parser.anchorSetHref(self, href); } - // TODO return a disposable string - pub fn get_port(self: *parser.Anchor, alloc: std.mem.Allocator) ![]const u8 { - var u = try url(self, alloc); - defer u.deinit(alloc); - - return try u.get_port(alloc); + pub fn get_port(self: *parser.Anchor, arena: std.mem.Allocator) ![]const u8 { + var u = try url(self, arena); + return try u.get_port(arena); } - pub fn set_port(self: *parser.Anchor, alloc: std.mem.Allocator, v: ?[]const u8) !void { - var u = try url(self, alloc); - defer u.deinit(alloc); - + pub fn set_port(self: *parser.Anchor, arena: std.mem.Allocator, v: ?[]const u8) !void { + var u = try url(self, arena); if (v != null and v.?.len > 0) { u.uri.port = try std.fmt.parseInt(u16, v.?, 10); } else { u.uri.port = null; } - const href = try u.format(alloc); - defer alloc.free(href); - + const href = try u.format(arena); try parser.anchorSetHref(self, href); } - // TODO return a disposable string - pub fn get_username(self: *parser.Anchor, alloc: std.mem.Allocator) ![]const u8 { - var u = try url(self, alloc); - defer u.deinit(alloc); - - return try alloc.dupe(u8, u.get_username()); + pub fn get_username(self: *parser.Anchor, arena: std.mem.Allocator) ![]const u8 { + var u = try url(self, arena); + return try arena.dupe(u8, u.get_username()); } - pub fn set_username(self: *parser.Anchor, alloc: std.mem.Allocator, v: ?[]const u8) !void { - var u = try url(self, alloc); - defer u.deinit(alloc); - + pub fn set_username(self: *parser.Anchor, arena: std.mem.Allocator, v: ?[]const u8) !void { + var u = try url(self, arena); if (v) |vv| { u.uri.user = .{ .raw = vv }; } else { u.uri.user = null; } - const href = try u.format(alloc); - defer alloc.free(href); - + const href = try u.format(arena); try parser.anchorSetHref(self, href); } - // TODO return a disposable string - pub fn get_password(self: *parser.Anchor, alloc: std.mem.Allocator) ![]const u8 { - var u = try url(self, alloc); - defer u.deinit(alloc); - - return try alloc.dupe(u8, u.get_password()); + pub fn get_password(self: *parser.Anchor, arena: std.mem.Allocator) ![]const u8 { + var u = try url(self, arena); + return try arena.dupe(u8, u.get_password()); } - pub fn set_password(self: *parser.Anchor, alloc: std.mem.Allocator, v: ?[]const u8) !void { - var u = try url(self, alloc); - defer u.deinit(alloc); + pub fn set_password(self: *parser.Anchor, arena: std.mem.Allocator, v: ?[]const u8) !void { + var u = try url(self, arena); if (v) |vv| { u.uri.password = .{ .raw = vv }; } else { u.uri.password = null; } - const href = try u.format(alloc); - defer alloc.free(href); - + const href = try u.format(arena); try parser.anchorSetHref(self, href); } - // TODO return a disposable string - pub fn get_pathname(self: *parser.Anchor, alloc: std.mem.Allocator) ![]const u8 { - var u = try url(self, alloc); - defer u.deinit(alloc); + pub fn get_pathname(self: *parser.Anchor, arena: std.mem.Allocator) ![]const u8 { + var u = try url(self, arena); + defer u.deinit(arena); - return try alloc.dupe(u8, u.get_pathname()); + return try arena.dupe(u8, u.get_pathname()); } - pub fn set_pathname(self: *parser.Anchor, alloc: std.mem.Allocator, v: []const u8) !void { - var u = try url(self, alloc); - defer u.deinit(alloc); + pub fn set_pathname(self: *parser.Anchor, arena: std.mem.Allocator, v: []const u8) !void { + var u = try url(self, arena); u.uri.path = .{ .raw = v }; - const href = try u.format(alloc); - defer alloc.free(href); + const href = try u.format(arena); try parser.anchorSetHref(self, href); } - // TODO return a disposable string - pub fn get_search(self: *parser.Anchor, alloc: std.mem.Allocator) ![]const u8 { - var u = try url(self, alloc); - defer u.deinit(alloc); - - return try u.get_search(alloc); + pub fn get_search(self: *parser.Anchor, arena: std.mem.Allocator) ![]const u8 { + var u = try url(self, arena); + return try u.get_search(arena); } - pub fn set_search(self: *parser.Anchor, alloc: std.mem.Allocator, v: ?[]const u8) !void { - var u = try url(self, alloc); - defer u.deinit(alloc); - + pub fn set_search(self: *parser.Anchor, arena: std.mem.Allocator, v: ?[]const u8) !void { + var u = try url(self, arena); if (v) |vv| { u.uri.query = .{ .raw = vv }; } else { u.uri.query = null; } - const href = try u.format(alloc); - defer alloc.free(href); + const href = try u.format(arena); try parser.anchorSetHref(self, href); } - // TODO return a disposable string - pub fn get_hash(self: *parser.Anchor, alloc: std.mem.Allocator) ![]const u8 { - var u = try url(self, alloc); - defer u.deinit(alloc); - - return try u.get_hash(alloc); + pub fn get_hash(self: *parser.Anchor, arena: std.mem.Allocator) ![]const u8 { + var u = try url(self, arena); + return try u.get_hash(arena); } - pub fn set_hash(self: *parser.Anchor, alloc: std.mem.Allocator, v: ?[]const u8) !void { - var u = try url(self, alloc); - defer u.deinit(alloc); - + pub fn set_hash(self: *parser.Anchor, arena: std.mem.Allocator, v: ?[]const u8) !void { + var u = try url(self, arena); if (v) |vv| { u.uri.fragment = .{ .raw = vv }; } else { u.uri.fragment = null; } - const href = try u.format(alloc); - defer alloc.free(href); + const href = try u.format(arena); try parser.anchorSetHref(self, href); } diff --git a/src/html/location.zig b/src/html/location.zig index 95a62daeb..adc3a2611 100644 --- a/src/html/location.zig +++ b/src/html/location.zig @@ -34,20 +34,20 @@ pub const Location = struct { pub fn deinit(_: *Location, _: std.mem.Allocator) void {} - pub fn get_href(self: *Location, alloc: std.mem.Allocator) ![]const u8 { - if (self.url) |*u| return u.get_href(alloc); + pub fn get_href(self: *Location, arena: std.mem.Allocator) ![]const u8 { + if (self.url) |*u| return u.get_href(arena); return ""; } - pub fn get_protocol(self: *Location, alloc: std.mem.Allocator) ![]const u8 { - if (self.url) |*u| return u.get_protocol(alloc); + pub fn get_protocol(self: *Location, arena: std.mem.Allocator) ![]const u8 { + if (self.url) |*u| return u.get_protocol(arena); return ""; } - pub fn get_host(self: *Location, alloc: std.mem.Allocator) ![]const u8 { - if (self.url) |*u| return u.get_host(alloc); + pub fn get_host(self: *Location, arena: std.mem.Allocator) ![]const u8 { + if (self.url) |*u| return u.get_host(arena); return ""; } @@ -58,8 +58,8 @@ pub const Location = struct { return ""; } - pub fn get_port(self: *Location, alloc: std.mem.Allocator) ![]const u8 { - if (self.url) |*u| return u.get_port(alloc); + pub fn get_port(self: *Location, arena: std.mem.Allocator) ![]const u8 { + if (self.url) |*u| return u.get_port(arena); return ""; } @@ -70,20 +70,20 @@ pub const Location = struct { return ""; } - pub fn get_search(self: *Location, alloc: std.mem.Allocator) ![]const u8 { - if (self.url) |*u| return u.get_search(alloc); + pub fn get_search(self: *Location, arena: std.mem.Allocator) ![]const u8 { + if (self.url) |*u| return u.get_search(arena); return ""; } - pub fn get_hash(self: *Location, alloc: std.mem.Allocator) ![]const u8 { - if (self.url) |*u| return u.get_hash(alloc); + pub fn get_hash(self: *Location, arena: std.mem.Allocator) ![]const u8 { + if (self.url) |*u| return u.get_hash(arena); return ""; } - pub fn get_origin(self: *Location, alloc: std.mem.Allocator) ![]const u8 { - if (self.url) |*u| return u.get_origin(alloc); + pub fn get_origin(self: *Location, arena: std.mem.Allocator) ![]const u8 { + if (self.url) |*u| return u.get_origin(arena); return ""; } @@ -101,8 +101,8 @@ pub const Location = struct { // TODO pub fn _reload(_: *Location) !void {} - pub fn _toString(self: *Location, alloc: std.mem.Allocator) ![]const u8 { - return try self.get_href(alloc); + pub fn _toString(self: *Location, arena: std.mem.Allocator) ![]const u8 { + return try self.get_href(arena); } }; diff --git a/src/url/url.zig b/src/url/url.zig index 2e28210d9..da09b9a8d 100644 --- a/src/url/url.zig +++ b/src/url/url.zig @@ -71,12 +71,8 @@ pub const URL = struct { self.search_params.deinit(alloc); } - // the caller must free the returned string. - // TODO return a disposable string - // https://github.com/lightpanda-io/jsruntime-lib/issues/195 - pub fn get_origin(self: *URL, alloc: std.mem.Allocator) ![]const u8 { - var buf = std.ArrayList(u8).init(alloc); - defer buf.deinit(); + pub fn get_origin(self: *URL, arena: std.mem.Allocator) ![]const u8 { + var buf = std.ArrayList(u8).init(arena); try self.uri.writeToStream(.{ .scheme = true, @@ -91,26 +87,20 @@ pub const URL = struct { // get_href returns the URL by writing all its components. // The query is replaced by a dump of search params. - // - // the caller must free the returned string. - // TODO return a disposable string - // https://github.com/lightpanda-io/jsruntime-lib/issues/195 - pub fn get_href(self: *URL, alloc: std.mem.Allocator) ![]const u8 { + pub fn get_href(self: *URL, arena: std.mem.Allocator) ![]const u8 { // retrieve the query search from search_params. const cur = self.uri.query; defer self.uri.query = cur; - var q = std.ArrayList(u8).init(alloc); - defer q.deinit(); + var q = std.ArrayList(u8).init(arena); try self.search_params.values.encode(q.writer()); self.uri.query = .{ .percent_encoded = q.items }; - return try self.format(alloc); + return try self.format(arena); } // format the url with all its components. - pub fn format(self: *URL, alloc: std.mem.Allocator) ![]const u8 { - var buf = std.ArrayList(u8).init(alloc); - defer buf.deinit(); + pub fn format(self: *URL, arena: std.mem.Allocator) ![]const u8 { + var buf = std.ArrayList(u8).init(arena); try self.uri.writeToStream(.{ .scheme = true, @@ -123,11 +113,8 @@ pub const URL = struct { return try buf.toOwnedSlice(); } - // the caller must free the returned string. - // TODO return a disposable string - // https://github.com/lightpanda-io/jsruntime-lib/issues/195 - pub fn get_protocol(self: *URL, alloc: std.mem.Allocator) ![]const u8 { - return try std.mem.concat(alloc, u8, &[_][]const u8{ self.uri.scheme, ":" }); + pub fn get_protocol(self: *URL, arena: std.mem.Allocator) ![]const u8 { + return try std.mem.concat(arena, u8, &[_][]const u8{ self.uri.scheme, ":" }); } pub fn get_username(self: *URL) []const u8 { @@ -138,12 +125,8 @@ pub const URL = struct { return uriComponentNullStr(self.uri.password); } - // the caller must free the returned string. - // TODO return a disposable string - // https://github.com/lightpanda-io/jsruntime-lib/issues/195 - pub fn get_host(self: *URL, alloc: std.mem.Allocator) ![]const u8 { - var buf = std.ArrayList(u8).init(alloc); - defer buf.deinit(); + pub fn get_host(self: *URL, arena: std.mem.Allocator) ![]const u8 { + var buf = std.ArrayList(u8).init(arena); try self.uri.writeToStream(.{ .scheme = false, @@ -153,24 +136,20 @@ pub const URL = struct { .query = false, .fragment = false, }, buf.writer()); - return try buf.toOwnedSlice(); + return buf.items; } pub fn get_hostname(self: *URL) []const u8 { return uriComponentNullStr(self.uri.host); } - // the caller must free the returned string. - // TODO return a disposable string - // https://github.com/lightpanda-io/jsruntime-lib/issues/195 - pub fn get_port(self: *URL, alloc: std.mem.Allocator) ![]const u8 { - if (self.uri.port == null) return try alloc.dupe(u8, ""); + pub fn get_port(self: *URL, arena: std.mem.Allocator) ![]const u8 { + if (self.uri.port == null) return ""; - var buf = std.ArrayList(u8).init(alloc); - defer buf.deinit(); + var buf = std.ArrayList(u8).init(arena); try std.fmt.formatInt(self.uri.port.?, 10, .lower, .{}, buf.writer()); - return try buf.toOwnedSlice(); + return buf.items; } pub fn get_pathname(self: *URL) []const u8 { @@ -178,35 +157,28 @@ pub const URL = struct { return uriComponentStr(self.uri.path); } - // the caller must free the returned string. - // TODO return a disposable string - // https://github.com/lightpanda-io/jsruntime-lib/issues/195 - pub fn get_search(self: *URL, alloc: std.mem.Allocator) ![]const u8 { - if (self.search_params.get_size() == 0) return try alloc.dupe(u8, ""); + pub fn get_search(self: *URL, arena: std.mem.Allocator) ![]const u8 { + if (self.search_params.get_size() == 0) return ""; var buf: std.ArrayListUnmanaged(u8) = .{}; - defer buf.deinit(alloc); - try buf.append(alloc, '?'); - try self.search_params.values.encode(buf.writer(alloc)); - return buf.toOwnedSlice(alloc); + try buf.append(arena, '?'); + try self.search_params.values.encode(buf.writer(arena)); + return buf.items; } - // the caller must free the returned string. - // TODO return a disposable string - // https://github.com/lightpanda-io/jsruntime-lib/issues/195 - pub fn get_hash(self: *URL, alloc: std.mem.Allocator) ![]const u8 { - if (self.uri.fragment == null) return try alloc.dupe(u8, ""); + pub fn get_hash(self: *URL, arena: std.mem.Allocator) ![]const u8 { + if (self.uri.fragment == null) return ""; - return try std.mem.concat(alloc, u8, &[_][]const u8{ "#", uriComponentNullStr(self.uri.fragment) }); + return try std.mem.concat(arena, u8, &[_][]const u8{ "#", uriComponentNullStr(self.uri.fragment) }); } pub fn get_searchParams(self: *URL) *URLSearchParams { return &self.search_params; } - pub fn _toJSON(self: *URL, alloc: std.mem.Allocator) ![]const u8 { - return try self.get_href(alloc); + pub fn _toJSON(self: *URL, arena: std.mem.Allocator) ![]const u8 { + return try self.get_href(arena); } }; diff --git a/src/xhr/xhr.zig b/src/xhr/xhr.zig index 9c4e82b35..37096f0be 100644 --- a/src/xhr/xhr.zig +++ b/src/xhr/xhr.zig @@ -362,7 +362,7 @@ pub const XMLHttpRequest = struct { pub fn _open( self: *XMLHttpRequest, - alloc: std.mem.Allocator, + arena: std.mem.Allocator, method: []const u8, url: []const u8, asyn: ?bool, @@ -380,7 +380,7 @@ pub const XMLHttpRequest = struct { self.reset(); - self.url = try self.origin_url.resolve(alloc, url); + self.url = try self.origin_url.resolve(arena, url); log.debug("open url ({s})", .{self.url.?}); self.sync = if (asyn) |b| !b else false; @@ -466,7 +466,7 @@ pub const XMLHttpRequest = struct { } // TODO body can be either a XMLHttpRequestBodyInit or a document - pub fn _send(self: *XMLHttpRequest, loop: *Loop, alloc: std.mem.Allocator, body: ?[]const u8) !void { + pub fn _send(self: *XMLHttpRequest, loop: *Loop, arena: std.mem.Allocator, body: ?[]const u8) !void { if (self.state != .opened) return DOMError.InvalidState; if (self.send_flag) return DOMError.InvalidState; @@ -485,7 +485,7 @@ pub const XMLHttpRequest = struct { { var arr: std.ArrayListUnmanaged(u8) = .{}; - try self.cookie_jar.forRequest(&self.url.?.uri, arr.writer(alloc), .{ + try self.cookie_jar.forRequest(&self.url.?.uri, arr.writer(arena), .{ .navigation = false, .origin_uri = &self.origin_url.uri, }); @@ -501,7 +501,7 @@ pub const XMLHttpRequest = struct { // var used_body: ?XMLHttpRequestBodyInit = null; if (body) |b| { if (self.method != .GET and self.method != .HEAD) { - request.body = try alloc.dupe(u8, b); + request.body = try arena.dupe(u8, b); try request.addHeader("Content-Type", "text/plain; charset=UTF-8", .{}); } } @@ -636,7 +636,7 @@ pub const XMLHttpRequest = struct { return url.raw; } - pub fn get_responseXML(self: *XMLHttpRequest, alloc: std.mem.Allocator) !?Response { + pub fn get_responseXML(self: *XMLHttpRequest, arena: std.mem.Allocator) !?Response { if (self.response_type != .Empty and self.response_type != .Document) { return DOMError.InvalidState; } @@ -652,7 +652,7 @@ pub const XMLHttpRequest = struct { }; } - self.setResponseObjDocument(alloc); + self.setResponseObjDocument(arena); if (self.response_obj) |obj| { return switch (obj) { @@ -665,7 +665,7 @@ pub const XMLHttpRequest = struct { } // https://xhr.spec.whatwg.org/#the-response-attribute - pub fn get_response(self: *XMLHttpRequest, alloc: std.mem.Allocator) !?Response { + pub fn get_response(self: *XMLHttpRequest, arena: std.mem.Allocator) !?Response { if (self.response_type == .Empty or self.response_type == .Text) { if (self.state == .loading or self.state == .done) { return .{ .Text = try self.get_responseText() }; @@ -703,7 +703,7 @@ pub const XMLHttpRequest = struct { // Otherwise, if this’s response type is "document", set a // document response for this. if (self.response_type == .Document) { - self.setResponseObjDocument(alloc); + self.setResponseObjDocument(arena); } if (self.response_type == .JSON) { @@ -712,7 +712,7 @@ pub const XMLHttpRequest = struct { // TODO Let jsonObject be the result of running parse JSON from bytes // on this’s received bytes. If that threw an exception, then return // null. - self.setResponseObjJSON(alloc); + self.setResponseObjJSON(arena); } if (self.response_obj) |obj| { @@ -731,7 +731,7 @@ pub const XMLHttpRequest = struct { // If the par sing fails, a Failure is stored in response_obj. // TODO parse XML. // https://xhr.spec.whatwg.org/#response-object - fn setResponseObjDocument(self: *XMLHttpRequest, alloc: std.mem.Allocator) void { + fn setResponseObjDocument(self: *XMLHttpRequest, arena: std.mem.Allocator) void { const response_mime = &self.response_mime.?; const isHTML = response_mime.isHTML(); @@ -739,11 +739,10 @@ pub const XMLHttpRequest = struct { // return. if (!isHTML) return; - const ccharset = alloc.dupeZ(u8, response_mime.charset orelse "utf-8") catch { + const ccharset = arena.dupeZ(u8, response_mime.charset orelse "utf-8") catch { self.response_obj = .{ .Failure = true }; return; }; - defer alloc.free(ccharset); var fbs = std.io.fixedBufferStream(self.response_bytes.items); const doc = parser.documentHTMLParse(fbs.reader(), ccharset) catch { @@ -760,12 +759,12 @@ pub const XMLHttpRequest = struct { } // setResponseObjJSON parses the received bytes as a std.json.Value. - fn setResponseObjJSON(self: *XMLHttpRequest, alloc: std.mem.Allocator) void { + fn setResponseObjJSON(self: *XMLHttpRequest, arena: std.mem.Allocator) void { // TODO should we use parseFromSliceLeaky if we expect the allocator is // already an arena? const p = std.json.parseFromSlice( JSONValue, - alloc, + arena, self.response_bytes.items, .{}, ) catch |e| { @@ -786,18 +785,13 @@ pub const XMLHttpRequest = struct { return self.response_headers.getFirstValue(name); } - // The caller owns the string returned. - // TODO change the return type to express the string ownership and let - // jsruntime free the string once copied to v8. - // see https://github.com/lightpanda-io/jsruntime-lib/issues/195 - pub fn _getAllResponseHeaders(self: *XMLHttpRequest, alloc: std.mem.Allocator) ![]const u8 { + pub fn _getAllResponseHeaders(self: *XMLHttpRequest, arena: std.mem.Allocator) ![]const u8 { if (self.response_headers.list.items.len == 0) return ""; self.response_headers.sort(); var buf: std.ArrayListUnmanaged(u8) = .{}; - errdefer buf.deinit(alloc); - const w = buf.writer(alloc); + const w = buf.writer(arena); for (self.response_headers.list.items) |entry| { if (entry.value.len == 0) continue; diff --git a/src/xmlserializer/xmlserializer.zig b/src/xmlserializer/xmlserializer.zig index a0153558a..ea39ba5b9 100644 --- a/src/xmlserializer/xmlserializer.zig +++ b/src/xmlserializer/xmlserializer.zig @@ -41,18 +41,15 @@ pub const XMLSerializer = struct { pub fn deinit(_: *XMLSerializer, _: std.mem.Allocator) void {} - pub fn _serializeToString(_: XMLSerializer, alloc: std.mem.Allocator, root: *parser.Node) ![]const u8 { - var buf = std.ArrayList(u8).init(alloc); - defer buf.deinit(); + pub fn _serializeToString(_: XMLSerializer, arena: std.mem.Allocator, root: *parser.Node) ![]const u8 { + var buf = std.ArrayList(u8).init(arena); if (try parser.nodeType(root) == .document) { try dump.writeHTML(@as(*parser.Document, @ptrCast(root)), buf.writer()); } else { try dump.writeNode(root, buf.writer()); } - // TODO express the caller owned the slice. - // https://github.com/lightpanda-io/jsruntime-lib/issues/195 - return try buf.toOwnedSlice(); + return buf.items; } };