diff --git a/src/browser/html/document.zig b/src/browser/html/document.zig
index f0b533d4..d5432036 100644
--- a/src/browser/html/document.zig
+++ b/src/browser/html/document.zig
@@ -174,6 +174,10 @@ pub const HTMLDocument = struct {
return try parser.documentHTMLGetLocation(Location, self);
}
+ pub fn set_location(_: *const parser.DocumentHTML, url: []const u8, page: *Page) !void {
+ return page.navigateFromWebAPI(url);
+ }
+
pub fn get_designMode(_: *parser.DocumentHTML) []const u8 {
return "off";
}
diff --git a/src/browser/html/location.zig b/src/browser/html/location.zig
index 604b9622..5fd2fb9f 100644
--- a/src/browser/html/location.zig
+++ b/src/browser/html/location.zig
@@ -69,18 +69,17 @@ pub const Location = struct {
return "";
}
- // TODO
- pub fn _assign(_: *Location, url: []const u8) !void {
- _ = url;
+ pub fn _assign(_: *const Location, url: []const u8, page: *Page) !void {
+ return page.navigateFromWebAPI(url);
}
- // TODO
- pub fn _replace(_: *Location, url: []const u8) !void {
- _ = url;
+ pub fn _replace(_: *const Location, url: []const u8, page: *Page) !void {
+ return page.navigateFromWebAPI(url);
}
- // TODO
- pub fn _reload(_: *Location) !void {}
+ pub fn _reload(_: *const Location, page: *Page) !void {
+ return page.navigateFromWebAPI(page.url.raw);
+ }
pub fn _toString(self: *Location, page: *Page) ![]const u8 {
return try self.get_href(page);
diff --git a/src/browser/html/window.zig b/src/browser/html/window.zig
index b58f7cbc..c0c2b98f 100644
--- a/src/browser/html/window.zig
+++ b/src/browser/html/window.zig
@@ -100,6 +100,10 @@ pub const Window = struct {
return &self.location;
}
+ pub fn set_location(_: *const Window, url: []const u8, page: *Page) !void {
+ return page.navigateFromWebAPI(url);
+ }
+
pub fn get_console(self: *Window) *Console {
return &self.console;
}
diff --git a/src/browser/page.zig b/src/browser/page.zig
index 54639b0d..2a18777c 100644
--- a/src/browser/page.zig
+++ b/src/browser/page.zig
@@ -541,23 +541,25 @@ pub const Page = struct {
.a => {
const element: *parser.Element = @ptrCast(node);
const href = (try parser.elementGetAttribute(element, "href")) orelse return;
-
- // We cannot navigate immediately as navigating will delete the DOM tree, which holds this event's node.
- // As such we schedule the function to be called as soon as possible.
- // NOTE Using the page.arena assumes that the scheduling loop does use this object after invoking the callback
- // If that changes we may want to consider storing DelayedNavigation in the session instead.
- const arena = self.arena;
- const navi = try arena.create(DelayedNavigation);
- navi.* = .{
- .session = self.session,
- .href = try arena.dupe(u8, href),
- };
- _ = try self.loop.timeout(0, &navi.navigate_node);
+ try self.navigateFromWebAPI(href);
},
else => {},
}
}
+ // As such we schedule the function to be called as soon as possible.
+ // The page.arena is safe to use here, but the transfer_arena exists
+ // specifically for this type of lifetime.
+ pub fn navigateFromWebAPI(self: *Page, url: []const u8) !void {
+ const arena = self.session.transfer_arena;
+ const navi = try arena.create(DelayedNavigation);
+ navi.* = .{
+ .session = self.session,
+ .url = try arena.dupe(u8, url),
+ };
+ _ = try self.loop.timeout(0, &navi.navigate_node);
+ }
+
pub fn getOrCreateNodeWrapper(self: *Page, comptime T: type, node: *parser.Node) !*T {
if (try self.getNodeWrapper(T, node)) |wrap| {
return wrap;
@@ -579,16 +581,15 @@ pub const Page = struct {
};
const DelayedNavigation = struct {
- navigate_node: Loop.CallbackNode = .{ .func = DelayedNavigation.delay_navigate },
+ url: []const u8,
session: *Session,
- href: []const u8,
+ navigate_node: Loop.CallbackNode = .{ .func = delayNavigate },
- fn delay_navigate(node: *Loop.CallbackNode, repeat_delay: *?u63) void {
+ fn delayNavigate(node: *Loop.CallbackNode, repeat_delay: *?u63) void {
_ = repeat_delay;
const self: *DelayedNavigation = @fieldParentPtr("navigate_node", node);
- self.session.pageNavigate(self.href) catch |err| {
- // TODO: should we trigger a specific event here?
- log.err(.page, "delayed navigation error", .{ .err = err });
+ self.session.pageNavigate(self.url) catch |err| {
+ log.err(.page, "delayed navigation error", .{ .err = err, .url = self.url });
};
}
};