Skip to content

Commit e1aec8b

Browse files
Merge pull request #230 from lightpanda-io/dom-url
URL api
2 parents 806b6c0 + d0c741f commit e1aec8b

File tree

6 files changed

+612
-87
lines changed

6 files changed

+612
-87
lines changed

src/apiweb.zig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const HTML = @import("html/html.zig");
77
const Events = @import("events/event.zig");
88
const XHR = @import("xhr/xhr.zig");
99
const Storage = @import("storage/storage.zig");
10+
const URL = @import("url/url.zig");
1011

1112
pub const HTMLDocument = @import("html/document.zig").HTMLDocument;
1213

@@ -18,4 +19,5 @@ pub const Interfaces = generate.Tuple(.{
1819
HTML.Interfaces,
1920
XHR.Interfaces,
2021
Storage.Interfaces,
22+
URL.Interfaces,
2123
});

src/browser/mime.zig

Lines changed: 6 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
const std = @import("std");
22
const testing = std.testing;
33

4+
const strparser = @import("../str/parser.zig");
5+
const Reader = strparser.Reader;
6+
const trim = strparser.trim;
7+
48
const Self = @This();
59

610
const MimeError = error{
@@ -21,91 +25,6 @@ pub const Empty = Self{ .mtype = "", .msubtype = "" };
2125
pub const HTML = Self{ .mtype = "text", .msubtype = "html" };
2226
pub const Javascript = Self{ .mtype = "application", .msubtype = "javascript" };
2327

24-
const reader = struct {
25-
s: []const u8,
26-
i: usize = 0,
27-
28-
fn until(self: *reader, c: u8) []const u8 {
29-
const ln = self.s.len;
30-
const start = self.i;
31-
while (self.i < ln) {
32-
if (c == self.s[self.i]) return self.s[start..self.i];
33-
self.i += 1;
34-
}
35-
36-
return self.s[start..self.i];
37-
}
38-
39-
fn tail(self: *reader) []const u8 {
40-
if (self.i > self.s.len) return "";
41-
defer self.i = self.s.len;
42-
return self.s[self.i..];
43-
}
44-
45-
fn skip(self: *reader) bool {
46-
if (self.i >= self.s.len) return false;
47-
self.i += 1;
48-
return true;
49-
}
50-
};
51-
52-
test "reader.skip" {
53-
var r = reader{ .s = "foo" };
54-
try testing.expect(r.skip());
55-
try testing.expect(r.skip());
56-
try testing.expect(r.skip());
57-
try testing.expect(!r.skip());
58-
try testing.expect(!r.skip());
59-
}
60-
61-
test "reader.tail" {
62-
var r = reader{ .s = "foo" };
63-
try testing.expectEqualStrings("foo", r.tail());
64-
try testing.expectEqualStrings("", r.tail());
65-
}
66-
67-
test "reader.until" {
68-
var r = reader{ .s = "foo.bar.baz" };
69-
try testing.expectEqualStrings("foo", r.until('.'));
70-
_ = r.skip();
71-
try testing.expectEqualStrings("bar", r.until('.'));
72-
_ = r.skip();
73-
try testing.expectEqualStrings("baz", r.until('.'));
74-
75-
r = reader{ .s = "foo" };
76-
try testing.expectEqualStrings("foo", r.until('.'));
77-
78-
r = reader{ .s = "" };
79-
try testing.expectEqualStrings("", r.until('.'));
80-
}
81-
82-
fn trim(s: []const u8) []const u8 {
83-
const ln = s.len;
84-
if (ln == 0) {
85-
return "";
86-
}
87-
var start: usize = 0;
88-
while (start < ln) {
89-
if (!std.ascii.isWhitespace(s[start])) break;
90-
start += 1;
91-
}
92-
93-
var end: usize = ln;
94-
while (end > 0) {
95-
if (!std.ascii.isWhitespace(s[end - 1])) break;
96-
end -= 1;
97-
}
98-
99-
return s[start..end];
100-
}
101-
102-
test "trim" {
103-
try testing.expectEqualStrings("", trim(""));
104-
try testing.expectEqualStrings("foo", trim("foo"));
105-
try testing.expectEqualStrings("foo", trim(" \n\tfoo"));
106-
try testing.expectEqualStrings("foo", trim("foo \n\t"));
107-
}
108-
10928
// https://mimesniff.spec.whatwg.org/#http-token-code-point
11029
fn isHTTPCodePoint(c: u8) bool {
11130
return switch (c) {
@@ -133,7 +52,7 @@ pub fn parse(s: []const u8) Self.MimeError!Self {
13352
if (ln > 255) return MimeError.TooBig;
13453

13554
var res = Self{ .mtype = "", .msubtype = "" };
136-
var r = reader{ .s = s };
55+
var r = Reader{ .s = s };
13756

13857
res.mtype = trim(r.until('/'));
13958
if (res.mtype.len == 0) return MimeError.Invalid;
@@ -150,7 +69,7 @@ pub fn parse(s: []const u8) Self.MimeError!Self {
15069

15170
// parse well known parameters.
15271
// don't check invalid parameter format.
153-
var rp = reader{ .s = res.params };
72+
var rp = Reader{ .s = res.params };
15473
while (true) {
15574
const name = trim(rp.until('='));
15675
if (!rp.skip()) return res;

src/run_tests.zig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ const apiweb = @import("apiweb.zig");
1010
const Window = @import("html/window.zig").Window;
1111
const xhr = @import("xhr/xhr.zig");
1212
const storage = @import("storage/storage.zig");
13+
const url = @import("url/url.zig");
14+
const urlquery = @import("url/query.zig");
1315

1416
const documentTestExecFn = @import("dom/document.zig").testExecFn;
1517
const HTMLDocumentTestExecFn = @import("html/document.zig").testExecFn;
@@ -30,6 +32,7 @@ const EventTestExecFn = @import("events/event.zig").testExecFn;
3032
const XHRTestExecFn = xhr.testExecFn;
3133
const ProgressEventTestExecFn = @import("xhr/progress_event.zig").testExecFn;
3234
const StorageTestExecFn = storage.testExecFn;
35+
const URLTestExecFn = url.testExecFn;
3336

3437
pub const Types = jsruntime.reflect(apiweb.Interfaces);
3538

@@ -95,6 +98,7 @@ fn testsAllExecFn(
9598
ProgressEventTestExecFn,
9699
ProcessingInstructionTestExecFn,
97100
StorageTestExecFn,
101+
URLTestExecFn,
98102
};
99103

100104
inline for (testFns) |testFn| {
@@ -261,6 +265,9 @@ test {
261265
const dumpTest = @import("browser/dump.zig");
262266
std.testing.refAllDecls(dumpTest);
263267

268+
const mimeTest = @import("browser/mime.zig");
269+
std.testing.refAllDecls(mimeTest);
270+
264271
const cssTest = @import("css/css.zig");
265272
std.testing.refAllDecls(cssTest);
266273

@@ -272,6 +279,9 @@ test {
272279

273280
const cssLibdomTest = @import("css/libdom_test.zig");
274281
std.testing.refAllDecls(cssLibdomTest);
282+
283+
const queryTest = @import("url/query.zig");
284+
std.testing.refAllDecls(queryTest);
275285
}
276286

277287
fn testJSRuntime(alloc: std.mem.Allocator) !void {

src/str/parser.zig

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
// some utils to parser strings.
2+
const std = @import("std");
3+
const testing = std.testing;
4+
5+
pub const Reader = struct {
6+
s: []const u8,
7+
i: usize = 0,
8+
9+
pub fn until(self: *Reader, c: u8) []const u8 {
10+
const ln = self.s.len;
11+
const start = self.i;
12+
while (self.i < ln) {
13+
if (c == self.s[self.i]) return self.s[start..self.i];
14+
self.i += 1;
15+
}
16+
17+
return self.s[start..self.i];
18+
}
19+
20+
pub fn tail(self: *Reader) []const u8 {
21+
if (self.i > self.s.len) return "";
22+
defer self.i = self.s.len;
23+
return self.s[self.i..];
24+
}
25+
26+
pub fn skip(self: *Reader) bool {
27+
if (self.i >= self.s.len) return false;
28+
self.i += 1;
29+
return true;
30+
}
31+
};
32+
33+
test "Reader.skip" {
34+
var r = Reader{ .s = "foo" };
35+
try testing.expect(r.skip());
36+
try testing.expect(r.skip());
37+
try testing.expect(r.skip());
38+
try testing.expect(!r.skip());
39+
try testing.expect(!r.skip());
40+
}
41+
42+
test "Reader.tail" {
43+
var r = Reader{ .s = "foo" };
44+
try testing.expectEqualStrings("foo", r.tail());
45+
try testing.expectEqualStrings("", r.tail());
46+
}
47+
48+
test "Reader.until" {
49+
var r = Reader{ .s = "foo.bar.baz" };
50+
try testing.expectEqualStrings("foo", r.until('.'));
51+
_ = r.skip();
52+
try testing.expectEqualStrings("bar", r.until('.'));
53+
_ = r.skip();
54+
try testing.expectEqualStrings("baz", r.until('.'));
55+
56+
r = Reader{ .s = "foo" };
57+
try testing.expectEqualStrings("foo", r.until('.'));
58+
59+
r = Reader{ .s = "" };
60+
try testing.expectEqualStrings("", r.until('.'));
61+
}
62+
63+
pub fn trim(s: []const u8) []const u8 {
64+
const ln = s.len;
65+
if (ln == 0) {
66+
return "";
67+
}
68+
var start: usize = 0;
69+
while (start < ln) {
70+
if (!std.ascii.isWhitespace(s[start])) break;
71+
start += 1;
72+
}
73+
74+
var end: usize = ln;
75+
while (end > 0) {
76+
if (!std.ascii.isWhitespace(s[end - 1])) break;
77+
end -= 1;
78+
}
79+
80+
return s[start..end];
81+
}
82+
83+
test "trim" {
84+
try testing.expectEqualStrings("", trim(""));
85+
try testing.expectEqualStrings("foo", trim("foo"));
86+
try testing.expectEqualStrings("foo", trim(" \n\tfoo"));
87+
try testing.expectEqualStrings("foo", trim("foo \n\t"));
88+
}

0 commit comments

Comments
 (0)