Skip to content

Commit 89bfc8c

Browse files
Merge pull request #222 from lightpanda-io/webstorage
storage: first implementation of webstorage API
2 parents 7c06067 + 5f6e5d5 commit 89bfc8c

File tree

8 files changed

+291
-1
lines changed

8 files changed

+291
-1
lines changed

src/apiweb.zig

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

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

@@ -16,4 +17,5 @@ pub const Interfaces = generate.Tuple(.{
1617
Events.Interfaces,
1718
HTML.Interfaces,
1819
XHR.Interfaces,
20+
Storage.Interfaces,
1921
});

src/browser/browser.zig

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ const apiweb = @import("../apiweb.zig");
1717
const Window = @import("../html/window.zig").Window;
1818
const Walker = @import("../dom/walker.zig").WalkerDepthFirst;
1919

20+
const storage = @import("../storage/storage.zig");
21+
2022
const FetchResult = std.http.Client.FetchResult;
2123

2224
const log = std.log.scoped(.browser);
@@ -69,6 +71,8 @@ pub const Session = struct {
6971
env: Env = undefined,
7072
loop: Loop,
7173
window: Window,
74+
// TODO move the shed to the browser?
75+
storageShed: storage.Shed,
7276

7377
jstypes: [Types.len]usize = undefined,
7478

@@ -81,6 +85,7 @@ pub const Session = struct {
8185
.window = Window.create(null),
8286
.loader = Loader.init(alloc),
8387
.loop = try Loop.init(alloc),
88+
.storageShed = storage.Shed.init(alloc),
8489
};
8590

8691
self.env = try Env.init(self.arena.allocator(), &self.loop);
@@ -95,6 +100,7 @@ pub const Session = struct {
95100

96101
self.loader.deinit();
97102
self.loop.deinit();
103+
self.storageShed.deinit();
98104
self.alloc.destroy(self);
99105
}
100106

@@ -116,6 +122,7 @@ pub const Page = struct {
116122
// handle url
117123
rawuri: ?[]const u8 = null,
118124
uri: std.Uri = undefined,
125+
origin: ?[]const u8 = null,
119126

120127
raw_data: ?[]const u8 = null,
121128

@@ -169,6 +176,15 @@ pub const Page = struct {
169176
self.rawuri = try alloc.dupe(u8, uri);
170177
self.uri = std.Uri.parse(self.rawuri.?) catch try std.Uri.parseWithoutScheme(self.rawuri.?);
171178

179+
// prepare origin value.
180+
var buf = std.ArrayList(u8).init(alloc);
181+
defer buf.deinit();
182+
try self.uri.writeToStream(.{
183+
.scheme = true,
184+
.authority = true,
185+
}, buf.writer());
186+
self.origin = try buf.toOwnedSlice();
187+
172188
// TODO handle fragment in url.
173189

174190
// load the data
@@ -237,6 +253,9 @@ pub const Page = struct {
237253
// TODO set the referrer to the document.
238254

239255
self.session.window.replaceDocument(html_doc);
256+
self.session.window.setStorageShelf(
257+
try self.session.storageShed.getOrPut(self.origin orelse "null"),
258+
);
240259

241260
// https://html.spec.whatwg.org/#read-html
242261

src/html/window.zig

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ const parser = @import("../netsurf.zig");
44

55
const EventTarget = @import("../dom/event_target.zig").EventTarget;
66

7+
const storage = @import("../storage/storage.zig");
8+
79
// https://dom.spec.whatwg.org/#interface-window-extensions
810
// https://html.spec.whatwg.org/multipage/nav-history-apis.html#window
911
pub const Window = struct {
@@ -17,6 +19,8 @@ pub const Window = struct {
1719
document: ?*parser.DocumentHTML = null,
1820
target: []const u8,
1921

22+
storageShelf: ?*storage.Shelf = null,
23+
2024
pub fn create(target: ?[]const u8) Window {
2125
return Window{
2226
.target = target orelse "",
@@ -27,6 +31,10 @@ pub const Window = struct {
2731
self.document = doc;
2832
}
2933

34+
pub fn setStorageShelf(self: *Window, shelf: *storage.Shelf) void {
35+
self.storageShelf = shelf;
36+
}
37+
3038
pub fn get_window(self: *Window) *Window {
3139
return self;
3240
}
@@ -46,4 +54,14 @@ pub const Window = struct {
4654
pub fn get_name(self: *Window) []const u8 {
4755
return self.target;
4856
}
57+
58+
pub fn get_localStorage(self: *Window) !*storage.Bottle {
59+
if (self.storageShelf == null) return parser.DOMError.NotSupported;
60+
return &self.storageShelf.?.bucket.local;
61+
}
62+
63+
pub fn get_sessionStorage(self: *Window) !*storage.Bottle {
64+
if (self.storageShelf == null) return parser.DOMError.NotSupported;
65+
return &self.storageShelf.?.bucket.session;
66+
}
4967
};

src/main_shell.zig

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const jsruntime = @import("jsruntime");
55
const parser = @import("netsurf.zig");
66
const apiweb = @import("apiweb.zig");
77
const Window = @import("html/window.zig").Window;
8+
const storage = @import("storage/storage.zig");
89

910
const html_test = @import("html_test.zig").html;
1011

@@ -20,9 +21,13 @@ fn execJS(
2021
try js_env.start(alloc);
2122
defer js_env.stop();
2223

24+
var storageShelf = storage.Shelf.init(alloc);
25+
defer storageShelf.deinit();
26+
2327
// alias global as self and window
2428
var window = Window.create(null);
2529
window.replaceDocument(doc);
30+
window.setStorageShelf(&storageShelf);
2631
try js_env.bindGlobal(window);
2732

2833
// launch shellExec

src/run_tests.zig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const parser = @import("netsurf.zig");
99
const apiweb = @import("apiweb.zig");
1010
const Window = @import("html/window.zig").Window;
1111
const xhr = @import("xhr/xhr.zig");
12+
const storage = @import("storage/storage.zig");
1213

1314
const documentTestExecFn = @import("dom/document.zig").testExecFn;
1415
const HTMLDocumentTestExecFn = @import("html/document.zig").testExecFn;
@@ -28,6 +29,7 @@ const ProcessingInstructionTestExecFn = @import("dom/processing_instruction.zig"
2829
const EventTestExecFn = @import("events/event.zig").testExecFn;
2930
const XHRTestExecFn = xhr.testExecFn;
3031
const ProgressEventTestExecFn = @import("xhr/progress_event.zig").testExecFn;
32+
const StorageTestExecFn = storage.testExecFn;
3133

3234
pub const Types = jsruntime.reflect(apiweb.Interfaces);
3335

@@ -45,6 +47,9 @@ fn testExecFn(
4547
try js_env.start(alloc);
4648
defer js_env.stop();
4749

50+
var storageShelf = storage.Shelf.init(alloc);
51+
defer storageShelf.deinit();
52+
4853
// document
4954
const file = try std.fs.cwd().openFile("test.html", .{});
5055
defer file.close();
@@ -56,7 +61,10 @@ fn testExecFn(
5661

5762
// alias global as self and window
5863
var window = Window.create(null);
64+
5965
window.replaceDocument(doc);
66+
window.setStorageShelf(&storageShelf);
67+
6068
try js_env.bindGlobal(window);
6169

6270
// run test
@@ -86,6 +94,7 @@ fn testsAllExecFn(
8694
XHRTestExecFn,
8795
ProgressEventTestExecFn,
8896
ProcessingInstructionTestExecFn,
97+
StorageTestExecFn,
8998
};
9099

91100
inline for (testFns) |testFn| {

0 commit comments

Comments
 (0)