Skip to content
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
4 changes: 4 additions & 0 deletions src/browser/html/document.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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";
}
Expand Down
15 changes: 7 additions & 8 deletions src/browser/html/location.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
4 changes: 4 additions & 0 deletions src/browser/html/window.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
37 changes: 19 additions & 18 deletions src/browser/page.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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 });
};
}
};
Expand Down