mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-03-22 04:34:44 +00:00
Add new Response and Request methods
-Response.blob -Response.clone -Request.blob -Request.text -Request.json -Request.arrayBuffer -Request.bytes -Request.clone
This commit is contained in:
@@ -98,6 +98,64 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<script id=mime_parsing>
|
||||||
|
// MIME types are lowercased
|
||||||
|
{
|
||||||
|
const blob = new Blob([], { type: "TEXT/HTML" });
|
||||||
|
testing.expectEqual("text/html", blob.type);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const blob = new Blob([], { type: "Application/JSON" });
|
||||||
|
testing.expectEqual("application/json", blob.type);
|
||||||
|
}
|
||||||
|
|
||||||
|
// MIME with parameters - lowercased
|
||||||
|
{
|
||||||
|
const blob = new Blob([], { type: "text/html; charset=UTF-8" });
|
||||||
|
testing.expectEqual("text/html; charset=utf-8", blob.type);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Any ASCII string is accepted and lowercased (no MIME structure validation)
|
||||||
|
{
|
||||||
|
const blob = new Blob([], { type: "invalid" });
|
||||||
|
testing.expectEqual("invalid", blob.type);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const blob = new Blob([], { type: "/" });
|
||||||
|
testing.expectEqual("/", blob.type);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Non-ASCII characters cause empty string (chars outside U+0020-U+007E)
|
||||||
|
{
|
||||||
|
const blob = new Blob([], { type: "ý/x" });
|
||||||
|
testing.expectEqual("", blob.type);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const blob = new Blob([], { type: "text/plàin" });
|
||||||
|
testing.expectEqual("", blob.type);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Control characters cause empty string
|
||||||
|
{
|
||||||
|
const blob = new Blob([], { type: "text/html\x00" });
|
||||||
|
testing.expectEqual("", blob.type);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Empty type stays empty
|
||||||
|
{
|
||||||
|
const blob = new Blob([]);
|
||||||
|
testing.expectEqual("", blob.type);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const blob = new Blob([], { type: "" });
|
||||||
|
testing.expectEqual("", blob.type);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
<script id=slice>
|
<script id=slice>
|
||||||
{
|
{
|
||||||
const parts = ["la", "symphonie", "des", "éclairs"];
|
const parts = ["la", "symphonie", "des", "éclairs"];
|
||||||
|
|||||||
@@ -137,3 +137,79 @@
|
|||||||
testing.expectEqual('PROPFIND', req.method);
|
testing.expectEqual('PROPFIND', req.method);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<script id=body_methods>
|
||||||
|
testing.async(async () => {
|
||||||
|
const req = new Request('https://example.com/api', {
|
||||||
|
method: 'POST',
|
||||||
|
body: 'Hello, World!',
|
||||||
|
headers: { 'Content-Type': 'text/plain' }
|
||||||
|
});
|
||||||
|
|
||||||
|
const text = await req.text();
|
||||||
|
testing.expectEqual('Hello, World!', text);
|
||||||
|
});
|
||||||
|
|
||||||
|
testing.async(async () => {
|
||||||
|
const req = new Request('https://example.com/api', {
|
||||||
|
method: 'POST',
|
||||||
|
body: '{"name": "test"}',
|
||||||
|
headers: { 'Content-Type': 'application/json' }
|
||||||
|
});
|
||||||
|
|
||||||
|
const json = await req.json();
|
||||||
|
testing.expectEqual('test', json.name);
|
||||||
|
});
|
||||||
|
|
||||||
|
testing.async(async () => {
|
||||||
|
const req = new Request('https://example.com/api', {
|
||||||
|
method: 'POST',
|
||||||
|
body: 'binary data',
|
||||||
|
headers: { 'Content-Type': 'application/octet-stream' }
|
||||||
|
});
|
||||||
|
|
||||||
|
const buffer = await req.arrayBuffer();
|
||||||
|
testing.expectEqual(true, buffer instanceof ArrayBuffer);
|
||||||
|
testing.expectEqual(11, buffer.byteLength);
|
||||||
|
});
|
||||||
|
|
||||||
|
testing.async(async () => {
|
||||||
|
const req = new Request('https://example.com/api', {
|
||||||
|
method: 'POST',
|
||||||
|
body: 'blob content',
|
||||||
|
headers: { 'Content-Type': 'text/plain' }
|
||||||
|
});
|
||||||
|
|
||||||
|
const blob = await req.blob();
|
||||||
|
testing.expectEqual(true, blob instanceof Blob);
|
||||||
|
testing.expectEqual(12, blob.size);
|
||||||
|
testing.expectEqual('text/plain', blob.type);
|
||||||
|
});
|
||||||
|
|
||||||
|
testing.async(async () => {
|
||||||
|
const req = new Request('https://example.com/api', {
|
||||||
|
method: 'POST',
|
||||||
|
body: 'bytes'
|
||||||
|
});
|
||||||
|
|
||||||
|
const bytes = await req.bytes();
|
||||||
|
testing.expectEqual(true, bytes instanceof Uint8Array);
|
||||||
|
testing.expectEqual(5, bytes.length);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script id=clone>
|
||||||
|
{
|
||||||
|
const req1 = new Request('https://example.com/api', {
|
||||||
|
method: 'POST',
|
||||||
|
body: 'test body',
|
||||||
|
headers: { 'X-Custom': 'value' }
|
||||||
|
});
|
||||||
|
|
||||||
|
const req2 = req1.clone();
|
||||||
|
|
||||||
|
testing.expectEqual(req1.url, req2.url);
|
||||||
|
testing.expectEqual(req1.method, req2.method);
|
||||||
|
testing.expectEqual('value', req2.headers.get('X-Custom'));
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|||||||
@@ -2,51 +2,113 @@
|
|||||||
<script src="../testing.js"></script>
|
<script src="../testing.js"></script>
|
||||||
|
|
||||||
<script id=response>
|
<script id=response>
|
||||||
// let response = new Response("Hello, World!");
|
{
|
||||||
// testing.expectEqual(200, response.status);
|
let response = new Response("Hello, World!");
|
||||||
// testing.expectEqual("", response.statusText);
|
testing.expectEqual(200, response.status);
|
||||||
// testing.expectEqual(true, response.ok);
|
testing.expectEqual("", response.statusText);
|
||||||
// testing.expectEqual("", response.url);
|
testing.expectEqual(true, response.ok);
|
||||||
// testing.expectEqual(false, response.redirected);
|
testing.expectEqual("", response.url);
|
||||||
|
testing.expectEqual(false, response.redirected);
|
||||||
|
}
|
||||||
|
|
||||||
let response2 = new Response("Error occurred", {
|
{
|
||||||
status: 404,
|
let response2 = new Response("Error occurred", {
|
||||||
statusText: "Not Found",
|
status: 404,
|
||||||
headers: {
|
statusText: "Not Found",
|
||||||
"Content-Type": "text/plain",
|
headers: {
|
||||||
"X-Custom": "test-value",
|
"Content-Type": "text/plain",
|
||||||
"Cache-Control": "no-cache"
|
"X-Custom": "test-value",
|
||||||
}
|
"Cache-Control": "no-cache"
|
||||||
});
|
}
|
||||||
testing.expectEqual(true, true);
|
|
||||||
// testing.expectEqual(404, response2.status);
|
|
||||||
// testing.expectEqual("Not Found", response2.statusText);
|
|
||||||
// testing.expectEqual(false, response2.ok);
|
|
||||||
// testing.expectEqual("text/plain", response2.headers);
|
|
||||||
// testing.expectEqual("test-value", response2.headers.get("X-Custom"));
|
|
||||||
testing.expectEqual("no-cache", response2.headers.get("cache-control"));
|
|
||||||
|
|
||||||
// let response3 = new Response("Created", { status: 201, statusText: "Created" });
|
|
||||||
// testing.expectEqual("basic", response3.type);
|
|
||||||
// testing.expectEqual(201, response3.status);
|
|
||||||
// testing.expectEqual("Created", response3.statusText);
|
|
||||||
// testing.expectEqual(true, response3.ok);
|
|
||||||
|
|
||||||
// let nullResponse = new Response(null);
|
|
||||||
// testing.expectEqual(200, nullResponse.status);
|
|
||||||
// testing.expectEqual("", nullResponse.statusText);
|
|
||||||
|
|
||||||
// let emptyResponse = new Response("");
|
|
||||||
// testing.expectEqual(200, emptyResponse.status);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<!-- <script id=json>
|
|
||||||
testing.async(async () => {
|
|
||||||
const json = await new Promise((resolve) => {
|
|
||||||
let response = new Response('[]');
|
|
||||||
response.json().then(resolve)
|
|
||||||
});
|
});
|
||||||
testing.expectEqual([], json);
|
testing.expectEqual(404, response2.status);
|
||||||
|
testing.expectEqual("Not Found", response2.statusText);
|
||||||
|
testing.expectEqual(false, response2.ok);
|
||||||
|
testing.expectEqual("test-value", response2.headers.get("X-Custom"));
|
||||||
|
testing.expectEqual("no-cache", response2.headers.get("cache-control"));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let response3 = new Response("Created", { status: 201, statusText: "Created" });
|
||||||
|
testing.expectEqual("basic", response3.type);
|
||||||
|
testing.expectEqual(201, response3.status);
|
||||||
|
testing.expectEqual("Created", response3.statusText);
|
||||||
|
testing.expectEqual(true, response3.ok);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let nullResponse = new Response(null);
|
||||||
|
testing.expectEqual(200, nullResponse.status);
|
||||||
|
testing.expectEqual("", nullResponse.statusText);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let emptyResponse = new Response("");
|
||||||
|
testing.expectEqual(200, emptyResponse.status);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script id=body_methods>
|
||||||
|
testing.async(async () => {
|
||||||
|
const response = new Response('Hello, World!');
|
||||||
|
const text = await response.text();
|
||||||
|
testing.expectEqual('Hello, World!', text);
|
||||||
|
});
|
||||||
|
|
||||||
|
testing.async(async () => {
|
||||||
|
const response = new Response('{"name": "test"}');
|
||||||
|
const json = await response.json();
|
||||||
|
testing.expectEqual('test', json.name);
|
||||||
|
});
|
||||||
|
|
||||||
|
testing.async(async () => {
|
||||||
|
const response = new Response('binary data');
|
||||||
|
const buffer = await response.arrayBuffer();
|
||||||
|
testing.expectEqual(true, buffer instanceof ArrayBuffer);
|
||||||
|
testing.expectEqual(11, buffer.byteLength);
|
||||||
|
});
|
||||||
|
|
||||||
|
testing.async(async () => {
|
||||||
|
const response = new Response('blob content', {
|
||||||
|
headers: { 'Content-Type': 'text/plain' }
|
||||||
|
});
|
||||||
|
const blob = await response.blob();
|
||||||
|
testing.expectEqual(true, blob instanceof Blob);
|
||||||
|
testing.expectEqual(12, blob.size);
|
||||||
|
testing.expectEqual('text/plain', blob.type);
|
||||||
|
});
|
||||||
|
|
||||||
|
testing.async(async () => {
|
||||||
|
const response = new Response('bytes');
|
||||||
|
const bytes = await response.bytes();
|
||||||
|
testing.expectEqual(true, bytes instanceof Uint8Array);
|
||||||
|
testing.expectEqual(5, bytes.length);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script id=clone>
|
||||||
|
{
|
||||||
|
const response1 = new Response('test body', {
|
||||||
|
status: 201,
|
||||||
|
statusText: 'Created',
|
||||||
|
headers: { 'X-Custom': 'value' }
|
||||||
|
});
|
||||||
|
|
||||||
|
const response2 = response1.clone();
|
||||||
|
|
||||||
|
testing.expectEqual(response1.status, response2.status);
|
||||||
|
testing.expectEqual(response1.statusText, response2.statusText);
|
||||||
|
testing.expectEqual('value', response2.headers.get('X-Custom'));
|
||||||
|
}
|
||||||
|
|
||||||
|
testing.async(async () => {
|
||||||
|
const response1 = new Response('cloned body');
|
||||||
|
const response2 = response1.clone();
|
||||||
|
|
||||||
|
const text1 = await response1.text();
|
||||||
|
const text2 = await response2.text();
|
||||||
|
|
||||||
|
testing.expectEqual('cloned body', text1);
|
||||||
|
testing.expectEqual('cloned body', text2);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
-->
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ const Writer = std.Io.Writer;
|
|||||||
|
|
||||||
const js = @import("../js/js.zig");
|
const js = @import("../js/js.zig");
|
||||||
const Page = @import("../Page.zig");
|
const Page = @import("../Page.zig");
|
||||||
|
const Mime = @import("../Mime.zig");
|
||||||
|
|
||||||
/// https://w3c.github.io/FileAPI/#blob-section
|
/// https://w3c.github.io/FileAPI/#blob-section
|
||||||
/// https://developer.mozilla.org/en-US/docs/Web/API/Blob
|
/// https://developer.mozilla.org/en-US/docs/Web/API/Blob
|
||||||
@@ -50,21 +51,50 @@ const InitOptions = struct {
|
|||||||
endings: []const u8 = "transparent",
|
endings: []const u8 = "transparent",
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Creates a new Blob.
|
/// Creates a new Blob (JS constructor).
|
||||||
pub fn init(
|
pub fn init(
|
||||||
maybe_blob_parts: ?[]const []const u8,
|
maybe_blob_parts: ?[]const []const u8,
|
||||||
maybe_options: ?InitOptions,
|
maybe_options: ?InitOptions,
|
||||||
page: *Page,
|
page: *Page,
|
||||||
|
) !*Blob {
|
||||||
|
return initWithMimeValidation(maybe_blob_parts, maybe_options, false, page);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a new Blob with optional MIME validation.
|
||||||
|
/// When validate_mime is true, uses full MIME parsing (for Response/Request).
|
||||||
|
/// When false, uses simple ASCII validation per FileAPI spec (for Blob constructor).
|
||||||
|
pub fn initWithMimeValidation(
|
||||||
|
maybe_blob_parts: ?[]const []const u8,
|
||||||
|
maybe_options: ?InitOptions,
|
||||||
|
validate_mime: bool,
|
||||||
|
page: *Page,
|
||||||
) !*Blob {
|
) !*Blob {
|
||||||
const options: InitOptions = maybe_options orelse .{};
|
const options: InitOptions = maybe_options orelse .{};
|
||||||
// Setup MIME; This can be any string according to my observations.
|
|
||||||
const mime: []const u8 = blk: {
|
const mime: []const u8 = blk: {
|
||||||
const t = options.type;
|
const t = options.type;
|
||||||
if (t.len == 0) {
|
if (t.len == 0) {
|
||||||
break :blk "";
|
break :blk "";
|
||||||
}
|
}
|
||||||
|
|
||||||
break :blk try page.arena.dupe(u8, t);
|
const buf = try page.arena.dupe(u8, t);
|
||||||
|
|
||||||
|
if (validate_mime) {
|
||||||
|
// Full MIME parsing per MIME sniff spec (for Content-Type headers)
|
||||||
|
_ = Mime.parse(buf) catch break :blk "";
|
||||||
|
} else {
|
||||||
|
// Simple validation per FileAPI spec (for Blob constructor):
|
||||||
|
// - If any char is outside U+0020-U+007E, return empty string
|
||||||
|
// - Otherwise lowercase
|
||||||
|
for (t) |c| {
|
||||||
|
if (c < 0x20 or c > 0x7E) {
|
||||||
|
break :blk "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ = std.ascii.lowerString(buf, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
break :blk buf;
|
||||||
};
|
};
|
||||||
|
|
||||||
const data = blk: {
|
const data = blk: {
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ const Http = @import("../../../http/Http.zig");
|
|||||||
const URL = @import("../URL.zig");
|
const URL = @import("../URL.zig");
|
||||||
const Page = @import("../../Page.zig");
|
const Page = @import("../../Page.zig");
|
||||||
const Headers = @import("Headers.zig");
|
const Headers = @import("Headers.zig");
|
||||||
|
const Blob = @import("../Blob.zig");
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
|
|
||||||
const Request = @This();
|
const Request = @This();
|
||||||
@@ -153,6 +154,55 @@ pub fn getHeaders(self: *Request, page: *Page) !*Headers {
|
|||||||
return headers;
|
return headers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn blob(self: *Request, page: *Page) !js.Promise {
|
||||||
|
const body = self._body orelse "";
|
||||||
|
const headers = try self.getHeaders(page);
|
||||||
|
const content_type = try headers.get("content-type", page) orelse "";
|
||||||
|
|
||||||
|
const b = try Blob.initWithMimeValidation(
|
||||||
|
&.{body},
|
||||||
|
.{ .type = content_type },
|
||||||
|
true,
|
||||||
|
page,
|
||||||
|
);
|
||||||
|
|
||||||
|
return page.js.local.?.resolvePromise(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn text(self: *const Request, page: *Page) !js.Promise {
|
||||||
|
const body = self._body orelse "";
|
||||||
|
return page.js.local.?.resolvePromise(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn json(self: *const Request, page: *Page) !js.Promise {
|
||||||
|
const body = self._body orelse "";
|
||||||
|
const local = page.js.local.?;
|
||||||
|
const value = local.parseJSON(body) catch |err| {
|
||||||
|
return local.rejectPromise(.{@errorName(err)});
|
||||||
|
};
|
||||||
|
return local.resolvePromise(try value.persist());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn arrayBuffer(self: *const Request, page: *Page) !js.Promise {
|
||||||
|
return page.js.local.?.resolvePromise(js.ArrayBuffer{ .values = self._body orelse "" });
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bytes(self: *const Request, page: *Page) !js.Promise {
|
||||||
|
return page.js.local.?.resolvePromise(js.TypedArray(u8){ .values = self._body orelse "" });
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clone(self: *const Request, page: *Page) !*Request {
|
||||||
|
return page._factory.create(Request{
|
||||||
|
._url = self._url,
|
||||||
|
._arena = self._arena,
|
||||||
|
._method = self._method,
|
||||||
|
._headers = self._headers,
|
||||||
|
._cache = self._cache,
|
||||||
|
._credentials = self._credentials,
|
||||||
|
._body = self._body,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
pub const JsApi = struct {
|
pub const JsApi = struct {
|
||||||
pub const bridge = js.Bridge(Request);
|
pub const bridge = js.Bridge(Request);
|
||||||
|
|
||||||
@@ -168,6 +218,12 @@ pub const JsApi = struct {
|
|||||||
pub const headers = bridge.accessor(Request.getHeaders, null, .{});
|
pub const headers = bridge.accessor(Request.getHeaders, null, .{});
|
||||||
pub const cache = bridge.accessor(Request.getCache, null, .{});
|
pub const cache = bridge.accessor(Request.getCache, null, .{});
|
||||||
pub const credentials = bridge.accessor(Request.getCredentials, null, .{});
|
pub const credentials = bridge.accessor(Request.getCredentials, null, .{});
|
||||||
|
pub const blob = bridge.function(Request.blob, .{});
|
||||||
|
pub const text = bridge.function(Request.text, .{});
|
||||||
|
pub const json = bridge.function(Request.json, .{});
|
||||||
|
pub const arrayBuffer = bridge.function(Request.arrayBuffer, .{});
|
||||||
|
pub const bytes = bridge.function(Request.bytes, .{});
|
||||||
|
pub const clone = bridge.function(Request.clone, .{});
|
||||||
};
|
};
|
||||||
|
|
||||||
const testing = @import("../../../testing.zig");
|
const testing = @import("../../../testing.zig");
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ const Http = @import("../../../http/Http.zig");
|
|||||||
const Page = @import("../../Page.zig");
|
const Page = @import("../../Page.zig");
|
||||||
const Headers = @import("Headers.zig");
|
const Headers = @import("Headers.zig");
|
||||||
const ReadableStream = @import("../streams/ReadableStream.zig");
|
const ReadableStream = @import("../streams/ReadableStream.zig");
|
||||||
|
const Blob = @import("../Blob.zig");
|
||||||
|
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
|
|
||||||
@@ -147,6 +148,47 @@ pub fn arrayBuffer(self: *const Response, page: *Page) !js.Promise {
|
|||||||
return page.js.local.?.resolvePromise(js.ArrayBuffer{ .values = self._body orelse "" });
|
return page.js.local.?.resolvePromise(js.ArrayBuffer{ .values = self._body orelse "" });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn blob(self: *const Response, page: *Page) !js.Promise {
|
||||||
|
const body = self._body orelse "";
|
||||||
|
const content_type = try self._headers.get("content-type", page) orelse "";
|
||||||
|
|
||||||
|
const b = try Blob.initWithMimeValidation(
|
||||||
|
&.{body},
|
||||||
|
.{ .type = content_type },
|
||||||
|
true,
|
||||||
|
page,
|
||||||
|
);
|
||||||
|
|
||||||
|
return page.js.local.?.resolvePromise(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bytes(self: *const Response, page: *Page) !js.Promise {
|
||||||
|
return page.js.local.?.resolvePromise(js.TypedArray(u8){ .values = self._body orelse "" });
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clone(self: *const Response, page: *Page) !*Response {
|
||||||
|
const arena = try page.getArena(.{ .debug = "Response.clone" });
|
||||||
|
errdefer page.releaseArena(arena);
|
||||||
|
|
||||||
|
const body = if (self._body) |b| try arena.dupe(u8, b) else null;
|
||||||
|
const status_text = try arena.dupe(u8, self._status_text);
|
||||||
|
const url = try arena.dupeZ(u8, self._url);
|
||||||
|
|
||||||
|
const cloned = try arena.create(Response);
|
||||||
|
cloned.* = .{
|
||||||
|
._arena = arena,
|
||||||
|
._status = self._status,
|
||||||
|
._status_text = status_text,
|
||||||
|
._url = url,
|
||||||
|
._body = body,
|
||||||
|
._type = self._type,
|
||||||
|
._is_redirected = self._is_redirected,
|
||||||
|
._headers = try Headers.init(.{ .obj = self._headers }, page),
|
||||||
|
._transfer = null,
|
||||||
|
};
|
||||||
|
return cloned;
|
||||||
|
}
|
||||||
|
|
||||||
pub const JsApi = struct {
|
pub const JsApi = struct {
|
||||||
pub const bridge = js.Bridge(Response);
|
pub const bridge = js.Bridge(Response);
|
||||||
|
|
||||||
@@ -170,6 +212,9 @@ pub const JsApi = struct {
|
|||||||
pub const url = bridge.accessor(Response.getURL, null, .{});
|
pub const url = bridge.accessor(Response.getURL, null, .{});
|
||||||
pub const redirected = bridge.accessor(Response.isRedirected, null, .{});
|
pub const redirected = bridge.accessor(Response.isRedirected, null, .{});
|
||||||
pub const arrayBuffer = bridge.function(Response.arrayBuffer, .{});
|
pub const arrayBuffer = bridge.function(Response.arrayBuffer, .{});
|
||||||
|
pub const blob = bridge.function(Response.blob, .{});
|
||||||
|
pub const bytes = bridge.function(Response.bytes, .{});
|
||||||
|
pub const clone = bridge.function(Response.clone, .{});
|
||||||
};
|
};
|
||||||
|
|
||||||
const testing = @import("../../../testing.zig");
|
const testing = @import("../../../testing.zig");
|
||||||
|
|||||||
Reference in New Issue
Block a user