Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

storage: first implementation of webstorage API #222

Merged
merged 3 commits into from
May 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/apiweb.zig
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const DOM = @import("dom/dom.zig");
const HTML = @import("html/html.zig");
const Events = @import("events/event.zig");
const XHR = @import("xhr/xhr.zig");
const Storage = @import("storage/storage.zig");

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

Expand All @@ -16,4 +17,5 @@ pub const Interfaces = generate.Tuple(.{
Events.Interfaces,
HTML.Interfaces,
XHR.Interfaces,
Storage.Interfaces,
});
19 changes: 19 additions & 0 deletions src/browser/browser.zig
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ const apiweb = @import("../apiweb.zig");
const Window = @import("../html/window.zig").Window;
const Walker = @import("../dom/walker.zig").WalkerDepthFirst;

const storage = @import("../storage/storage.zig");

const FetchResult = std.http.Client.FetchResult;

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

jstypes: [Types.len]usize = undefined,

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

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

self.loader.deinit();
self.loop.deinit();
self.storageShed.deinit();
self.alloc.destroy(self);
}

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

raw_data: ?[]const u8 = null,

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

// prepare origin value.
var buf = std.ArrayList(u8).init(alloc);
defer buf.deinit();
try self.uri.writeToStream(.{
.scheme = true,
.authority = true,
}, buf.writer());
self.origin = try buf.toOwnedSlice();

// TODO handle fragment in url.

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

self.session.window.replaceDocument(html_doc);
self.session.window.setStorageShelf(
try self.session.storageShed.getOrPut(self.origin orelse "null"),
);

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

Expand Down
18 changes: 18 additions & 0 deletions src/html/window.zig
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ const parser = @import("../netsurf.zig");

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

const storage = @import("../storage/storage.zig");

// https://dom.spec.whatwg.org/#interface-window-extensions
// https://html.spec.whatwg.org/multipage/nav-history-apis.html#window
pub const Window = struct {
Expand All @@ -17,6 +19,8 @@ pub const Window = struct {
document: ?*parser.DocumentHTML = null,
target: []const u8,

storageShelf: ?*storage.Shelf = null,

pub fn create(target: ?[]const u8) Window {
return Window{
.target = target orelse "",
Expand All @@ -27,6 +31,10 @@ pub const Window = struct {
self.document = doc;
}

pub fn setStorageShelf(self: *Window, shelf: *storage.Shelf) void {
self.storageShelf = shelf;
}

pub fn get_window(self: *Window) *Window {
return self;
}
Expand All @@ -46,4 +54,14 @@ pub const Window = struct {
pub fn get_name(self: *Window) []const u8 {
return self.target;
}

pub fn get_localStorage(self: *Window) !*storage.Bottle {
if (self.storageShelf == null) return parser.DOMError.NotSupported;
return &self.storageShelf.?.bucket.local;
}

pub fn get_sessionStorage(self: *Window) !*storage.Bottle {
if (self.storageShelf == null) return parser.DOMError.NotSupported;
return &self.storageShelf.?.bucket.session;
}
};
5 changes: 5 additions & 0 deletions src/main_shell.zig
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const jsruntime = @import("jsruntime");
const parser = @import("netsurf.zig");
const apiweb = @import("apiweb.zig");
const Window = @import("html/window.zig").Window;
const storage = @import("storage/storage.zig");

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

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

var storageShelf = storage.Shelf.init(alloc);
defer storageShelf.deinit();

// alias global as self and window
var window = Window.create(null);
window.replaceDocument(doc);
window.setStorageShelf(&storageShelf);
try js_env.bindGlobal(window);

// launch shellExec
Expand Down
9 changes: 9 additions & 0 deletions src/run_tests.zig
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const parser = @import("netsurf.zig");
const apiweb = @import("apiweb.zig");
const Window = @import("html/window.zig").Window;
const xhr = @import("xhr/xhr.zig");
const storage = @import("storage/storage.zig");

const documentTestExecFn = @import("dom/document.zig").testExecFn;
const HTMLDocumentTestExecFn = @import("html/document.zig").testExecFn;
Expand All @@ -28,6 +29,7 @@ const ProcessingInstructionTestExecFn = @import("dom/processing_instruction.zig"
const EventTestExecFn = @import("events/event.zig").testExecFn;
const XHRTestExecFn = xhr.testExecFn;
const ProgressEventTestExecFn = @import("xhr/progress_event.zig").testExecFn;
const StorageTestExecFn = storage.testExecFn;

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

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

var storageShelf = storage.Shelf.init(alloc);
defer storageShelf.deinit();

// document
const file = try std.fs.cwd().openFile("test.html", .{});
defer file.close();
Expand All @@ -56,7 +61,10 @@ fn testExecFn(

// alias global as self and window
var window = Window.create(null);

window.replaceDocument(doc);
window.setStorageShelf(&storageShelf);

try js_env.bindGlobal(window);

// run test
Expand Down Expand Up @@ -86,6 +94,7 @@ fn testsAllExecFn(
XHRTestExecFn,
ProgressEventTestExecFn,
ProcessingInstructionTestExecFn,
StorageTestExecFn,
};

inline for (testFns) |testFn| {
Expand Down
Loading