diff --git a/src/browser/js/Context.zig b/src/browser/js/Context.zig
index dc297b21..1273a4b7 100644
--- a/src/browser/js/Context.zig
+++ b/src/browser/js/Context.zig
@@ -807,6 +807,12 @@ pub fn jsValueToZig(self: *Context, comptime T: type, js_value: v8.Value) !T {
unreachable;
},
.@"enum" => |e| {
+ if (@hasDecl(T, "js_enum_from_string")) {
+ if (!js_value.isString()) {
+ return error.InvalidArgument;
+ }
+ return std.meta.stringToEnum(T, try self.valueToString(js_value, .{})) orelse return error.InvalidArgument;
+ }
switch (@typeInfo(e.tag_type)) {
.int => return std.meta.intToEnum(T, try jsIntToZig(e.tag_type, js_value, self.v8_context)),
else => @compileError("unsupported enum parameter type: " ++ @typeName(T)),
diff --git a/src/browser/tests/legacy/fetch/fetch.html b/src/browser/tests/legacy/fetch/fetch.html
index 877f887b..5e4a46e0 100644
--- a/src/browser/tests/legacy/fetch/fetch.html
+++ b/src/browser/tests/legacy/fetch/fetch.html
@@ -1,9 +1,9 @@
+
diff --git a/src/browser/tests/net/response.html b/src/browser/tests/net/response.html
new file mode 100644
index 00000000..c632c3ff
--- /dev/null
+++ b/src/browser/tests/net/response.html
@@ -0,0 +1,50 @@
+
+
+
+
+
+
diff --git a/src/browser/webapi/net/Request.zig b/src/browser/webapi/net/Request.zig
index d053b434..235773d7 100644
--- a/src/browser/webapi/net/Request.zig
+++ b/src/browser/webapi/net/Request.zig
@@ -33,6 +33,8 @@ _method: Http.Method,
_headers: ?*Headers,
_body: ?[]const u8,
_arena: Allocator,
+_cache: Cache,
+_credentials: Credentials,
pub const Input = union(enum) {
request: *Request,
@@ -43,6 +45,25 @@ pub const InitOpts = struct {
method: ?[]const u8 = null,
headers: ?Headers.InitOpts = null,
body: ?[]const u8 = null,
+ cache: Cache = .default,
+ credentials: Credentials = .@"same-origin",
+};
+
+const Credentials = enum {
+ omit,
+ include,
+ @"same-origin",
+ pub const js_enum_from_string = true;
+};
+
+const Cache = enum {
+ default,
+ @"no-store",
+ @"reload",
+ @"no-cache",
+ @"force-cache",
+ @"only-if-cached",
+ pub const js_enum_from_string = true;
};
pub fn init(input: Input, opts_: ?InitOpts, page: *Page) !*Request {
@@ -80,6 +101,8 @@ pub fn init(input: Input, opts_: ?InitOpts, page: *Page) !*Request {
._arena = arena,
._method = method,
._headers = headers,
+ ._cache = opts.cache,
+ ._credentials = opts.credentials,
._body = body,
});
}
@@ -111,6 +134,14 @@ pub fn getMethod(self: *const Request) []const u8 {
return @tagName(self._method);
}
+pub fn getCache(self: *const Request) []const u8 {
+ return @tagName(self._cache);
+}
+
+pub fn getCredentials(self: *const Request) []const u8 {
+ return @tagName(self._credentials);
+}
+
pub fn getHeaders(self: *Request, page: *Page) !*Headers {
if (self._headers) |headers| {
return headers;
@@ -134,6 +165,8 @@ pub const JsApi = struct {
pub const url = bridge.accessor(Request.getUrl, null, .{});
pub const method = bridge.accessor(Request.getMethod, null, .{});
pub const headers = bridge.accessor(Request.getHeaders, null, .{});
+ pub const cache = bridge.accessor(Request.getCache, null, .{});
+ pub const credentials = bridge.accessor(Request.getCredentials, null, .{});
};
const testing = @import("../../../testing.zig");
diff --git a/src/browser/webapi/net/Response.zig b/src/browser/webapi/net/Response.zig
index dffa4c60..68dd8ed7 100644
--- a/src/browser/webapi/net/Response.zig
+++ b/src/browser/webapi/net/Response.zig
@@ -39,10 +39,11 @@ _arena: Allocator,
_headers: *Headers,
_body: ?[]const u8,
_type: Type,
+_status_text: []const u8,
const InitOpts = struct {
status: u16 = 200,
- headers: ?*Headers = null,
+ headers: ?Headers.InitOpts = null,
statusText: ?[]const u8 = null,
};
@@ -51,13 +52,15 @@ pub fn init(body_: ?[]const u8, opts_: ?InitOpts, page: *Page) !*Response {
// Store empty string as empty string, not null
const body = if (body_) |b| try page.arena.dupe(u8, b) else null;
+ const status_text = if (opts.statusText) |st| try page.dupeString(st) else "";
return page._factory.create(Response{
._arena = page.arena,
._status = opts.status,
+ ._status_text = status_text,
._body = body,
- ._headers = opts.headers orelse try Headers.init(null, page),
- ._type = .basic, // @ZIGDOM: todo
+ ._type = .basic,
+ ._headers = try Headers.init(opts.headers, page),
});
}
@@ -65,6 +68,21 @@ pub fn getStatus(self: *const Response) u16 {
return self._status;
}
+pub fn getStatusText(self: *const Response) []const u8 {
+ // This property is meant to actually capture the response status text, not
+ // just return the text representation of self._status. If we do,
+ // new Response(null, {status: 200}).statusText, we should get empty string.
+ return self._status_text;
+}
+
+pub fn getURL(_: *const Response) []const u8 {
+ return "";
+}
+
+pub fn isRedirected(_: *const Response) bool {
+ return false;
+}
+
pub fn getHeaders(self: *const Response) *Headers {
return self._headers;
}
@@ -90,6 +108,7 @@ pub fn isOK(self: *const Response) bool {
return self._status >= 200 and self._status <= 299;
}
+
pub fn getText(self: *const Response, page: *Page) !js.Promise {
const body = self._body orelse "";
return page.js.resolvePromise(body);
@@ -120,9 +139,17 @@ pub const JsApi = struct {
pub const constructor = bridge.constructor(Response.init, .{});
pub const ok = bridge.accessor(Response.isOK, null, .{});
pub const status = bridge.accessor(Response.getStatus, null, .{});
+ pub const statusText = bridge.accessor(Response.getStatusText, null, .{});
pub const @"type" = bridge.accessor(Response.getType, null, .{});
pub const text = bridge.function(Response.getText, .{});
pub const json = bridge.function(Response.getJson, .{});
pub const headers = bridge.accessor(Response.getHeaders, null, .{});
pub const body = bridge.accessor(Response.getBody, null, .{});
+ pub const url = bridge.accessor(Response.getURL, null, .{});
+ pub const redirected = bridge.accessor(Response.isRedirected, null, .{});
};
+
+const testing = @import("../../../testing.zig");
+test "WebApi: Response" {
+ try testing.htmlRunner("net/response.html", .{});
+}