URLSearchParams from FormData

This commit is contained in:
Karl Seguin
2025-12-13 12:47:54 +08:00
parent eab328e2b5
commit 52dcc6765a
4 changed files with 25 additions and 19 deletions

View File

@@ -81,7 +81,6 @@
testing.expectEqual(3, ups.size); testing.expectEqual(3, ups.size);
testing.expectEqual(['1', '2'], ups.getAll('a')); testing.expectEqual(['1', '2'], ups.getAll('a'));
testing.expectEqual(['3'], ups.getAll('b')); testing.expectEqual(['3'], ups.getAll('b'));
fd.delete('a'); // the two aren't linked, it created a copy fd.delete('a'); // the two aren't linked, it created a copy

View File

@@ -353,3 +353,17 @@
testing.expectEqual(['a', 'a', 'b', 'b', 'c'], Array.from(usp.keys())); testing.expectEqual(['a', 'a', 'b', 'b', 'c'], Array.from(usp.keys()));
} }
</script> </script>
<script id=formData>
{
let fd = new FormData();
fd.append('a', '1');
fd.append('a', '2');
fd.append('b', '3');
ups = new URLSearchParams(fd);
testing.expectEqual(3, ups.size);
testing.expectEqual(['1', '2'], ups.getAll('a'));
testing.expectEqual(['3'], ups.getAll('b'));
}
</script>

View File

@@ -35,23 +35,6 @@ _search_params: ?*URLSearchParams = null,
pub const resolve = @import("../URL.zig").resolve; pub const resolve = @import("../URL.zig").resolve;
pub const eqlDocument = @import("../URL.zig").eqlDocument; pub const eqlDocument = @import("../URL.zig").eqlDocument;
pub fn canParse(url: []const u8, base_: ?[]const u8, page: *Page) bool {
_ = page;
const url_is_absolute = U.isCompleteHTTPUrl(url);
if (base_) |b| {
// Base must be valid even if URL is absolute
if (!U.isCompleteHTTPUrl(b)) {
return false;
}
return true;
} else if (!url_is_absolute) {
return false;
} else {
return true;
}
}
pub fn init(url: [:0]const u8, base_: ?[:0]const u8, page: *Page) !*URL { pub fn init(url: [:0]const u8, base_: ?[:0]const u8, page: *Page) !*URL {
const url_is_absolute = @import("../URL.zig").isCompleteHTTPUrl(url); const url_is_absolute = @import("../URL.zig").isCompleteHTTPUrl(url);
@@ -238,6 +221,13 @@ pub fn toString(self: *const URL, page: *const Page) ![:0]const u8 {
return buf.written()[0 .. buf.written().len - 1 :0]; return buf.written()[0 .. buf.written().len - 1 :0];
} }
pub fn canParse(url: []const u8, base_: ?[]const u8) bool {
if (base_) |b| {
return U.isCompleteHTTPUrl(b);
}
return U.isCompleteHTTPUrl(url);
}
pub const JsApi = struct { pub const JsApi = struct {
pub const bridge = js.Bridge(URL); pub const bridge = js.Bridge(URL);

View File

@@ -24,8 +24,9 @@ const String = @import("../../../string.zig").String;
const Allocator = std.mem.Allocator; const Allocator = std.mem.Allocator;
const Page = @import("../../Page.zig"); const Page = @import("../../Page.zig");
const GenericIterator = @import("../collections/iterator.zig").Entry; const FormData = @import("FormData.zig");
const KeyValueList = @import("../KeyValueList.zig"); const KeyValueList = @import("../KeyValueList.zig");
const GenericIterator = @import("../collections/iterator.zig").Entry;
const URLSearchParams = @This(); const URLSearchParams = @This();
@@ -33,6 +34,7 @@ _arena: Allocator,
_params: KeyValueList, _params: KeyValueList,
const InitOpts = union(enum) { const InitOpts = union(enum) {
form_data: *FormData,
value: js.Value, value: js.Value,
query_string: []const u8, query_string: []const u8,
}; };
@@ -43,6 +45,7 @@ pub fn init(opts_: ?InitOpts, page: *Page) !*URLSearchParams {
const opts = opts_ orelse break :blk .empty; const opts = opts_ orelse break :blk .empty;
switch (opts) { switch (opts) {
.query_string => |qs| break :blk try paramsFromString(arena, qs, &page.buf), .query_string => |qs| break :blk try paramsFromString(arena, qs, &page.buf),
.form_data => |fd| break :blk try KeyValueList.copy(arena, fd._list),
.value => |js_val| { .value => |js_val| {
if (js_val.isObject()) { if (js_val.isObject()) {
break :blk try KeyValueList.fromJsObject(arena, js_val.toObject(), null, page); break :blk try KeyValueList.fromJsObject(arena, js_val.toObject(), null, page);