@@ -35,6 +35,7 @@ const Navigation = @This();
3535const NavigationKind = @import ("root.zig" ).NavigationKind ;
3636const NavigationHistoryEntry = @import ("root.zig" ).NavigationHistoryEntry ;
3737const NavigationTransition = @import ("root.zig" ).NavigationTransition ;
38+ const NavigationState = @import ("root.zig" ).NavigationState ;
3839const NavigationCurrentEntryChangeEvent = @import ("root.zig" ).NavigationCurrentEntryChangeEvent ;
3940
4041const NavigationEventTarget = @import ("NavigationEventTarget.zig" );
@@ -110,10 +111,10 @@ pub fn _forward(self: *Navigation, page: *Page) !NavigationReturn {
110111pub fn updateEntries (self : * Navigation , url : []const u8 , kind : NavigationKind , page : * Page , dispatch : bool ) ! void {
111112 switch (kind ) {
112113 .replace = > {
113- _ = try self .replaceEntry (url , null , page , dispatch );
114+ _ = try self .replaceEntry (url , .{ . source = .navigation , . value = null } , page , dispatch );
114115 },
115116 .push = > | state | {
116- _ = try self .pushEntry (url , state , page , dispatch );
117+ _ = try self .pushEntry (url , .{ . source = .navigation , . value = state } , page , dispatch );
117118 },
118119 .traverse = > | index | {
119120 self .index = index ;
@@ -132,7 +133,13 @@ pub fn processNavigation(self: *Navigation, page: *Page) !void {
132133
133134/// Pushes an entry into the Navigation stack WITHOUT actually navigating to it.
134135/// For that, use `navigate`.
135- pub fn pushEntry (self : * Navigation , _url : []const u8 , state : ? []const u8 , page : * Page , dispatch : bool ) ! * NavigationHistoryEntry {
136+ pub fn pushEntry (
137+ self : * Navigation ,
138+ _url : []const u8 ,
139+ state : NavigationState ,
140+ page : * Page ,
141+ dispatch : bool ,
142+ ) ! * NavigationHistoryEntry {
136143 const arena = page .session .arena ;
137144
138145 const url = try arena .dupe (u8 , _url );
@@ -160,18 +167,24 @@ pub fn pushEntry(self: *Navigation, _url: []const u8, state: ?[]const u8, page:
160167 // we don't always have a current entry...
161168 const previous = if (self .entries .items .len > 0 ) self .currentEntry () else null ;
162169 try self .entries .append (arena , entry );
170+ self .index = index ;
171+
163172 if (previous ) | prev | {
164173 if (dispatch ) {
165174 NavigationCurrentEntryChangeEvent .dispatch (self , prev , .push );
166175 }
167176 }
168177
169- self .index = index ;
170-
171178 return entry ;
172179}
173180
174- pub fn replaceEntry (self : * Navigation , _url : []const u8 , state : ? []const u8 , page : * Page , dispatch : bool ) ! * NavigationHistoryEntry {
181+ pub fn replaceEntry (
182+ self : * Navigation ,
183+ _url : []const u8 ,
184+ state : NavigationState ,
185+ page : * Page ,
186+ dispatch : bool ,
187+ ) ! * NavigationHistoryEntry {
175188 const arena = page .session .arena ;
176189 const url = try arena .dupe (u8 , _url );
177190
@@ -184,7 +197,7 @@ pub fn replaceEntry(self: *Navigation, _url: []const u8, state: ?[]const u8, pag
184197 const entry = try arena .create (NavigationHistoryEntry );
185198 entry .* = NavigationHistoryEntry {
186199 .id = id_str ,
187- .key = id_str ,
200+ .key = previous . key ,
188201 .url = url ,
189202 .state = state ,
190203 };
@@ -242,7 +255,20 @@ pub fn navigate(
242255 // todo: Fire navigate event
243256 try finished .resolve ({});
244257
245- _ = try self .pushEntry (url , state , page , true );
258+ _ = try self .pushEntry (url , .{ .source = .navigation , .value = state }, page , true );
259+ } else {
260+ try page .navigateFromWebAPI (url , .{ .reason = .navigation }, kind );
261+ }
262+ },
263+ .replace = > | state | {
264+ if (is_same_document ) {
265+ page .url = new_url ;
266+
267+ try committed .resolve ({});
268+ // todo: Fire navigate event
269+ try finished .resolve ({});
270+
271+ _ = try self .replaceEntry (url , .{ .source = .navigation , .value = state }, page , true );
246272 } else {
247273 try page .navigateFromWebAPI (url , .{ .reason = .navigation }, kind );
248274 }
@@ -263,7 +289,6 @@ pub fn navigate(
263289 .reload = > {
264290 try page .navigateFromWebAPI (url , .{ .reason = .navigation }, kind );
265291 },
266- else = > unreachable ,
267292 }
268293
269294 return .{
@@ -275,7 +300,13 @@ pub fn navigate(
275300pub fn _navigate (self : * Navigation , _url : []const u8 , _opts : ? NavigateOptions , page : * Page ) ! NavigationReturn {
276301 const opts = _opts orelse NavigateOptions {};
277302 const json = if (opts .state ) | state | state .toJson (page .session .arena ) catch return error .DataClone else null ;
278- return try self .navigate (_url , .{ .push = json }, page );
303+
304+ const kind : NavigationKind = switch (opts .history ) {
305+ .replace = > .{ .replace = json },
306+ .push , .auto = > .{ .push = json },
307+ };
308+
309+ return try self .navigate (_url , kind , page );
279310}
280311
281312pub const ReloadOptions = struct {
@@ -290,7 +321,7 @@ pub fn _reload(self: *Navigation, _opts: ?ReloadOptions, page: *Page) !Navigatio
290321 const entry = self .currentEntry ();
291322 if (opts .state ) | state | {
292323 const previous = entry ;
293- entry .state = state .toJson (arena ) catch return error .DataClone ;
324+ entry .state = .{ . source = .navigation , . value = state .toJson (arena ) catch return error .DataClone } ;
294325 NavigationCurrentEntryChangeEvent .dispatch (self , previous , .reload );
295326 }
296327
@@ -323,6 +354,6 @@ pub fn _updateCurrentEntry(self: *Navigation, options: UpdateCurrentEntryOptions
323354 const arena = page .session .arena ;
324355
325356 const previous = self .currentEntry ();
326- self .currentEntry ().state = options .state .toJson (arena ) catch return error .DataClone ;
357+ self .currentEntry ().state = .{ . source = .navigation , . value = options .state .toJson (arena ) catch return error .DataClone } ;
327358 NavigationCurrentEntryChangeEvent .dispatch (self , previous , null );
328359}
0 commit comments