diff --git a/src/browser/tests/element/inner.html b/src/browser/tests/element/inner.html index b8023122..c9bb0894 100644 --- a/src/browser/tests/element/inner.html +++ b/src/browser/tests/element/inner.html @@ -143,7 +143,6 @@ // innerText does NOT parse HTML (unlike innerHTML) d1.innerText = 'hello
world
!!'; testing.expectEqual('hello
world
!!', d1.innerText); - console.warn(d1.innerHTML); testing.expectEqual('hello <div>world</div><b>!!</b>', d1.innerHTML); // Setting empty string clears children diff --git a/src/browser/tests/net/headers.html b/src/browser/tests/net/headers.html index d0d1c35e..07e96725 100644 --- a/src/browser/tests/net/headers.html +++ b/src/browser/tests/net/headers.html @@ -17,15 +17,145 @@ testing.expectEqual(null, headers.get('Content-Type')); testing.expectEqual(false, headers.has('Content-Type')); } + + + + diff --git a/src/browser/webapi/collections/NodeList.zig b/src/browser/webapi/collections/NodeList.zig index 0e4a3c2e..dae61509 100644 --- a/src/browser/webapi/collections/NodeList.zig +++ b/src/browser/webapi/collections/NodeList.zig @@ -75,7 +75,7 @@ pub fn forEach(self: *NodeList, cb: js.Function, page: *Page) !void { var result: js.Function.Result = undefined; cb.tryCall(void, .{ next.value, i, self }, &result) catch { - log.debug(.js, "forEach callback", .{ .err = result.exception, .stack = result.stack }); + log.debug(.js, "forEach callback", .{ .err = result.exception, .stack = result.stack, .source = "nodelist" }); return; }; } diff --git a/src/browser/webapi/net/Headers.zig b/src/browser/webapi/net/Headers.zig index 9dea0b95..136207bd 100644 --- a/src/browser/webapi/net/Headers.zig +++ b/src/browser/webapi/net/Headers.zig @@ -1,5 +1,6 @@ const std = @import("std"); const js = @import("../../js/js.zig"); +const log = @import("../../../log.zig"); const Page = @import("../../Page.zig"); const KeyValueList = @import("../KeyValueList.zig"); @@ -15,27 +16,58 @@ pub fn init(page: *Page) !*Headers { } pub fn append(self: *Headers, name: []const u8, value: []const u8, page: *Page) !void { - try self._list.append(page.arena, name, value); + const normalized_name = normalizeHeaderName(name, page); + try self._list.append(page.arena, normalized_name, value); } -pub fn delete(self: *Headers, name: []const u8) void { - self._list.delete(name, null); +pub fn delete(self: *Headers, name: []const u8, page: *Page) void { + const normalized_name = normalizeHeaderName(name, page); + self._list.delete(normalized_name, null); } -pub fn get(self: *const Headers, name: []const u8) ?[]const u8 { - return self._list.get(name); +pub fn get(self: *const Headers, name: []const u8, page: *Page) ?[]const u8 { + const normalized_name = normalizeHeaderName(name, page); + return self._list.get(normalized_name); } -pub fn getAll(self: *const Headers, name: []const u8, page: *Page) ![]const []const u8 { - return self._list.getAll(name, page); -} - -pub fn has(self: *const Headers, name: []const u8) bool { - return self._list.has(name); +pub fn has(self: *const Headers, name: []const u8, page: *Page) bool { + const normalized_name = normalizeHeaderName(name, page); + return self._list.has(normalized_name); } pub fn set(self: *Headers, name: []const u8, value: []const u8, page: *Page) !void { - try self._list.set(page.arena, name, value); + const normalized_name = normalizeHeaderName(name, page); + try self._list.set(page.arena, normalized_name, value); +} + +pub fn keys(self: *Headers, page: *Page) !*KeyValueList.KeyIterator { + return KeyValueList.KeyIterator.init(.{ .list = self, .kv = &self._list }, page); +} + +pub fn values(self: *Headers, page: *Page) !*KeyValueList.ValueIterator { + return KeyValueList.ValueIterator.init(.{ .list = self, .kv = &self._list }, page); +} + +pub fn entries(self: *Headers, page: *Page) !*KeyValueList.EntryIterator { + return KeyValueList.EntryIterator.init(.{ .list = self, .kv = &self._list }, page); +} + +pub fn forEach(self: *Headers, cb_: js.Function, js_this_: ?js.Object) !void { + const cb = if (js_this_) |js_this| try cb_.withThis(js_this) else cb_; + + for (self._list._entries.items) |entry| { + var result: js.Function.Result = undefined; + cb.tryCall(void, .{ entry.value.str(), entry.name.str(), self }, &result) catch { + log.debug(.js, "forEach callback", .{ .err = result.exception, .stack = result.stack, .source = "headers" }); + }; + } +} + +fn normalizeHeaderName(name: []const u8, page: *Page) []const u8 { + if (name.len > page.buf.len) { + return name; + } + return std.ascii.lowerString(&page.buf, name); } pub const JsApi = struct { @@ -51,9 +83,12 @@ pub const JsApi = struct { pub const append = bridge.function(Headers.append, .{}); pub const delete = bridge.function(Headers.delete, .{}); pub const get = bridge.function(Headers.get, .{}); - pub const getAll = bridge.function(Headers.getAll, .{}); pub const has = bridge.function(Headers.has, .{}); pub const set = bridge.function(Headers.set, .{}); + pub const keys = bridge.function(Headers.keys, .{}); + pub const values = bridge.function(Headers.values, .{}); + pub const entries = bridge.function(Headers.entries, .{}); + pub const forEach = bridge.function(Headers.forEach, .{}); }; const testing = @import("../../../testing.zig");