Skip to content

Commit f2f7a34

Browse files
authored
Merge pull request #715 from lightpanda-io/location_change
Implement location.reload(), location.assign() and location setter
2 parents f696aa3 + 58215a4 commit f2f7a34

File tree

4 files changed

+34
-26
lines changed

4 files changed

+34
-26
lines changed

src/browser/html/document.zig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,10 @@ pub const HTMLDocument = struct {
174174
return try parser.documentHTMLGetLocation(Location, self);
175175
}
176176

177+
pub fn set_location(_: *const parser.DocumentHTML, url: []const u8, page: *Page) !void {
178+
return page.navigateFromWebAPI(url);
179+
}
180+
177181
pub fn get_designMode(_: *parser.DocumentHTML) []const u8 {
178182
return "off";
179183
}

src/browser/html/location.zig

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -69,18 +69,17 @@ pub const Location = struct {
6969
return "";
7070
}
7171

72-
// TODO
73-
pub fn _assign(_: *Location, url: []const u8) !void {
74-
_ = url;
72+
pub fn _assign(_: *const Location, url: []const u8, page: *Page) !void {
73+
return page.navigateFromWebAPI(url);
7574
}
7675

77-
// TODO
78-
pub fn _replace(_: *Location, url: []const u8) !void {
79-
_ = url;
76+
pub fn _replace(_: *const Location, url: []const u8, page: *Page) !void {
77+
return page.navigateFromWebAPI(url);
8078
}
8179

82-
// TODO
83-
pub fn _reload(_: *Location) !void {}
80+
pub fn _reload(_: *const Location, page: *Page) !void {
81+
return page.navigateFromWebAPI(page.url.raw);
82+
}
8483

8584
pub fn _toString(self: *Location, page: *Page) ![]const u8 {
8685
return try self.get_href(page);

src/browser/html/window.zig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@ pub const Window = struct {
100100
return &self.location;
101101
}
102102

103+
pub fn set_location(_: *const Window, url: []const u8, page: *Page) !void {
104+
return page.navigateFromWebAPI(url);
105+
}
106+
103107
pub fn get_console(self: *Window) *Console {
104108
return &self.console;
105109
}

src/browser/page.zig

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -550,23 +550,25 @@ pub const Page = struct {
550550
.a => {
551551
const element: *parser.Element = @ptrCast(node);
552552
const href = (try parser.elementGetAttribute(element, "href")) orelse return;
553-
554-
// We cannot navigate immediately as navigating will delete the DOM tree, which holds this event's node.
555-
// As such we schedule the function to be called as soon as possible.
556-
// NOTE Using the page.arena assumes that the scheduling loop does use this object after invoking the callback
557-
// If that changes we may want to consider storing DelayedNavigation in the session instead.
558-
const arena = self.arena;
559-
const navi = try arena.create(DelayedNavigation);
560-
navi.* = .{
561-
.session = self.session,
562-
.href = try arena.dupe(u8, href),
563-
};
564-
_ = try self.loop.timeout(0, &navi.navigate_node);
553+
try self.navigateFromWebAPI(href);
565554
},
566555
else => {},
567556
}
568557
}
569558

559+
// As such we schedule the function to be called as soon as possible.
560+
// The page.arena is safe to use here, but the transfer_arena exists
561+
// specifically for this type of lifetime.
562+
pub fn navigateFromWebAPI(self: *Page, url: []const u8) !void {
563+
const arena = self.session.transfer_arena;
564+
const navi = try arena.create(DelayedNavigation);
565+
navi.* = .{
566+
.session = self.session,
567+
.url = try arena.dupe(u8, url),
568+
};
569+
_ = try self.loop.timeout(0, &navi.navigate_node);
570+
}
571+
570572
pub fn getOrCreateNodeWrapper(self: *Page, comptime T: type, node: *parser.Node) !*T {
571573
if (self.getNodeWrapper(T, node)) |wrap| {
572574
return wrap;
@@ -588,16 +590,15 @@ pub const Page = struct {
588590
};
589591

590592
const DelayedNavigation = struct {
591-
navigate_node: Loop.CallbackNode = .{ .func = DelayedNavigation.delay_navigate },
593+
url: []const u8,
592594
session: *Session,
593-
href: []const u8,
595+
navigate_node: Loop.CallbackNode = .{ .func = delayNavigate },
594596

595-
fn delay_navigate(node: *Loop.CallbackNode, repeat_delay: *?u63) void {
597+
fn delayNavigate(node: *Loop.CallbackNode, repeat_delay: *?u63) void {
596598
_ = repeat_delay;
597599
const self: *DelayedNavigation = @fieldParentPtr("navigate_node", node);
598-
self.session.pageNavigate(self.href) catch |err| {
599-
// TODO: should we trigger a specific event here?
600-
log.err(.page, "delayed navigation error", .{ .err = err });
600+
self.session.pageNavigate(self.url) catch |err| {
601+
log.err(.page, "delayed navigation error", .{ .err = err, .url = self.url });
601602
};
602603
}
603604
};

0 commit comments

Comments
 (0)