diff --git a/src/browser/browser.zig b/src/browser/browser.zig index 65aafa83..e361838e 100644 --- a/src/browser/browser.zig +++ b/src/browser/browser.zig @@ -36,6 +36,9 @@ const apiweb = @import("../apiweb.zig"); const Window = @import("../html/window.zig").Window; const Walker = @import("../dom/walker.zig").WalkerDepthFirst; +const URL = @import("../url/url.zig").URL; +const Location = @import("../html/location.zig").Location; + const storage = @import("../storage/storage.zig"); const FetchResult = @import("../http/Client.zig").Client.FetchResult; @@ -102,7 +105,9 @@ pub const Session = struct { loader: Loader, env: Env = undefined, inspector: ?jsruntime.Inspector = null, + window: Window, + // TODO move the shed to the browser? storageShed: storage.Shed, page: ?Page = null, @@ -201,6 +206,10 @@ pub const Page = struct { uri: std.Uri = undefined, origin: ?[]const u8 = null, + // html url and location + url: ?URL = null, + location: Location = .{}, + raw_data: ?[]const u8 = null, fn init( @@ -244,6 +253,13 @@ pub const Page = struct { self.session.env.stop(); // TODO unload document: https://html.spec.whatwg.org/#unloading-documents + if (self.url) |*u| u.deinit(self.arena.allocator()); + self.url = null; + self.location.url = null; + self.session.window.replaceLocation(&self.location) catch |e| { + log.err("reset window location: {any}", .{e}); + }; + // clear netsurf memory arena. parser.deinit(); @@ -308,6 +324,11 @@ pub const Page = struct { self.rawuri = try alloc.dupe(u8, uri); self.uri = std.Uri.parse(self.rawuri.?) catch try std.Uri.parseAfterScheme("", self.rawuri.?); + if (self.url) |*prev| prev.deinit(alloc); + self.url = try URL.constructor(alloc, self.rawuri.?, null); + self.location.url = &self.url.?; + try self.session.window.replaceLocation(&self.location); + // prepare origin value. var buf = std.ArrayList(u8).init(alloc); defer buf.deinit(); diff --git a/src/html/location.zig b/src/html/location.zig index b1ec2913..70e69025 100644 --- a/src/html/location.zig +++ b/src/html/location.zig @@ -114,8 +114,16 @@ pub fn testExecFn( js_env: *jsruntime.Env, ) anyerror!void { var location = [_]Case{ - .{ .src = "location.href", .ex = "" }, - .{ .src = "document.location.href", .ex = "" }, + .{ .src = "location.href", .ex = "https://lightpanda.io/opensource-browser/" }, + .{ .src = "document.location.href", .ex = "https://lightpanda.io/opensource-browser/" }, + + .{ .src = "location.host", .ex = "lightpanda.io" }, + .{ .src = "location.hostname", .ex = "lightpanda.io" }, + .{ .src = "location.origin", .ex = "https://lightpanda.io" }, + .{ .src = "location.pathname", .ex = "/opensource-browser/" }, + .{ .src = "location.hash", .ex = "" }, + .{ .src = "location.port", .ex = "" }, + .{ .src = "location.search", .ex = "" }, }; try checkCases(js_env, &location); } diff --git a/src/html/window.zig b/src/html/window.zig index b5530857..42aef90d 100644 --- a/src/html/window.zig +++ b/src/html/window.zig @@ -31,6 +31,8 @@ const Location = @import("location.zig").Location; const storage = @import("../storage/storage.zig"); +var emptyLocation = Location{}; + // https://dom.spec.whatwg.org/#interface-window-extensions // https://html.spec.whatwg.org/multipage/nav-history-apis.html#window pub const Window = struct { @@ -44,7 +46,7 @@ pub const Window = struct { document: ?*parser.DocumentHTML = null, target: []const u8, history: History = .{}, - location: Location = .{}, + location: *Location = &emptyLocation, storageShelf: ?*storage.Shelf = null, @@ -62,17 +64,17 @@ pub const Window = struct { }; } - pub fn replaceLocation(self: *Window, loc: Location) !void { + pub fn replaceLocation(self: *Window, loc: *Location) !void { self.location = loc; - if (self.doc != null) { - try parser.documentHTMLSetLocation(Location, self.doc.?, &self.location); + if (self.document != null) { + try parser.documentHTMLSetLocation(Location, self.document.?, self.location); } } pub fn replaceDocument(self: *Window, doc: *parser.DocumentHTML) !void { self.document = doc; - try parser.documentHTMLSetLocation(Location, doc, &self.location); + try parser.documentHTMLSetLocation(Location, doc, self.location); } pub fn setStorageShelf(self: *Window, shelf: *storage.Shelf) void { @@ -88,7 +90,7 @@ pub const Window = struct { } pub fn get_location(self: *Window) *Location { - return &self.location; + return self.location; } pub fn get_self(self: *Window) *Window { diff --git a/src/run_tests.zig b/src/run_tests.zig index 7481d266..bc0b5631 100644 --- a/src/run_tests.zig +++ b/src/run_tests.zig @@ -29,8 +29,10 @@ const Window = @import("html/window.zig").Window; const xhr = @import("xhr/xhr.zig"); const storage = @import("storage/storage.zig"); const url = @import("url/url.zig"); +const URL = url.URL; const urlquery = @import("url/query.zig"); const Client = @import("asyncio").Client; +const Location = @import("html/location.zig").Location; const documentTestExecFn = @import("dom/document.zig").testExecFn; const HTMLDocumentTestExecFn = @import("html/document.zig").testExecFn; @@ -98,6 +100,11 @@ fn testExecFn( // alias global as self and window var window = Window.create(null, null); + var u = try URL.constructor(alloc, "https://lightpanda.io/opensource-browser/", null); + defer u.deinit(alloc); + var location = Location{ .url = &u }; + try window.replaceLocation(&location); + try window.replaceDocument(doc); window.setStorageShelf(&storageShelf);