From c009669ec8682dceb10bf2b327ac8d98a520a227 Mon Sep 17 00:00:00 2001 From: Muki Kiboigo Date: Sun, 2 Nov 2025 21:07:50 -0800 Subject: [PATCH] properly handle replace navigation case --- src/browser/navigation/Navigation.zig | 62 +++++++++++++++++++-------- src/browser/page.zig | 4 +- 2 files changed, 45 insertions(+), 21 deletions(-) diff --git a/src/browser/navigation/Navigation.zig b/src/browser/navigation/Navigation.zig index 13b009e2..8f700ecf 100644 --- a/src/browser/navigation/Navigation.zig +++ b/src/browser/navigation/Navigation.zig @@ -101,28 +101,27 @@ pub fn _forward(self: *Navigation, page: *Page) !NavigationReturn { return self.navigate(next_entry.url, .{ .traverse = new_index }, page); } +pub fn updateEntries(self: *Navigation, url: []const u8, kind: NavigationKind, page: *Page, dispatch: bool) !void { + switch (kind) { + .replace => { + _ = try self.replaceEntry(url, null, page, dispatch); + }, + .push => |state| { + _ = try self.pushEntry(url, state, page, dispatch); + }, + .traverse => |index| { + self.index = index; + }, + .reload => {}, + } +} + // This is for after true navigation processing, where we need to ensure that our entries are up to date. // This is only really safe to run in the `pageDoneCallback` where we can guarantee that the URL and NavigationKind are correct. pub fn processNavigation(self: *Navigation, page: *Page) !void { const url = page.url.raw; - const kind = page.session.navigation_kind; - - if (kind) |k| { - switch (k) { - .replace => { - // When replacing, we just update the URL but the state is nullified. - const entry = self.currentEntry(); - entry.url = url; - entry.state = null; - }, - .push => |state| { - _ = try self.pushEntry(url, state, page, false); - }, - .traverse, .reload => {}, - } - } else { - _ = try self.pushEntry(url, null, page, false); - } + const kind: NavigationKind = page.session.navigation_kind orelse .{ .push = null }; + try self.updateEntries(url, kind, page, false); } /// Pushes an entry into the Navigation stack WITHOUT actually navigating to it. @@ -166,6 +165,33 @@ pub fn pushEntry(self: *Navigation, _url: []const u8, state: ?[]const u8, page: return entry; } +pub fn replaceEntry(self: *Navigation, _url: []const u8, state: ?[]const u8, page: *Page, dispatch: bool) !*NavigationHistoryEntry { + const arena = page.session.arena; + const url = try arena.dupe(u8, _url); + + const previous = self.currentEntry(); + + const id = self.next_entry_id; + self.next_entry_id += 1; + const id_str = try std.fmt.allocPrint(arena, "{d}", .{id}); + + const entry = try arena.create(NavigationHistoryEntry); + entry.* = NavigationHistoryEntry{ + .id = id_str, + .key = id_str, + .url = url, + .state = state, + }; + + self.entries.items[self.index] = entry; + + if (dispatch) { + NavigationCurrentEntryChangeEvent.dispatch(self, previous, .replace); + } + + return entry; +} + const NavigateOptions = struct { const NavigateOptionsHistory = enum { pub const ENUM_JS_USE_TAG = true; diff --git a/src/browser/page.zig b/src/browser/page.zig index b7eb7c15..579dd6d5 100644 --- a/src/browser/page.zig +++ b/src/browser/page.zig @@ -1075,9 +1075,7 @@ pub const Page = struct { if (try self.url.eqlDocument(&new_url, session.transfer_arena)) { self.url = new_url; - - const prev = session.navigation.currentEntry(); - NavigationCurrentEntryChangeEvent.dispatch(&self.session.navigation, prev, kind); + try session.navigation.updateEntries(stitched_url, kind, self, true); return; } }