diff --git a/src/browser/html/History.zig b/src/browser/html/History.zig index 6d0b0828..69739f6a 100644 --- a/src/browser/html/History.zig +++ b/src/browser/html/History.zig @@ -48,7 +48,7 @@ pub fn set_scrollRestoration(self: *History, mode: ScrollRestorationMode) void { } pub fn get_state(_: *History, page: *Page) !?js.Value { - if (page.session.navigation.currentEntry().state) |state| { + if (page.session.navigation.currentEntry().state.value) |state| { const value = try js.Value.fromJson(page.js, state); return value; } else { @@ -61,7 +61,7 @@ pub fn _pushState(_: *const History, state: js.Object, _: ?[]const u8, _url: ?[] const url = if (_url) |u| try arena.dupe(u8, u) else try arena.dupe(u8, page.url.raw); const json = state.toJson(arena) catch return error.DataClone; - _ = try page.session.navigation.pushEntry(url, json, page, true); + _ = try page.session.navigation.pushEntry(url, .{ .source = .history, .value = json }, page, true); } pub fn _replaceState(_: *const History, state: js.Object, _: ?[]const u8, _url: ?[]const u8, page: *Page) !void { @@ -69,7 +69,7 @@ pub fn _replaceState(_: *const History, state: js.Object, _: ?[]const u8, _url: const url = if (_url) |u| try arena.dupe(u8, u) else try arena.dupe(u8, page.url.raw); const json = try state.toJson(arena); - _ = try page.session.navigation.replaceEntry(url, json, page, true); + _ = try page.session.navigation.replaceEntry(url, .{ .source = .history, .value = json }, page, true); } pub fn go(_: *const History, delta: i32, page: *Page) !void { @@ -86,7 +86,7 @@ pub fn go(_: *const History, delta: i32, page: *Page) !void { if (entry.url) |url| { if (try page.isSameOrigin(url)) { - PopStateEvent.dispatch(entry.state, page); + PopStateEvent.dispatch(entry.state.value, page); } } diff --git a/src/browser/navigation/Navigation.zig b/src/browser/navigation/Navigation.zig index 3c6bfcfd..222a51e0 100644 --- a/src/browser/navigation/Navigation.zig +++ b/src/browser/navigation/Navigation.zig @@ -35,6 +35,7 @@ const Navigation = @This(); const NavigationKind = @import("root.zig").NavigationKind; const NavigationHistoryEntry = @import("root.zig").NavigationHistoryEntry; const NavigationTransition = @import("root.zig").NavigationTransition; +const NavigationState = @import("root.zig").NavigationState; const NavigationCurrentEntryChangeEvent = @import("root.zig").NavigationCurrentEntryChangeEvent; const NavigationEventTarget = @import("NavigationEventTarget.zig"); @@ -110,10 +111,10 @@ pub fn _forward(self: *Navigation, page: *Page) !NavigationReturn { 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); + _ = try self.replaceEntry(url, .{ .source = .navigation, .value = null }, page, dispatch); }, .push => |state| { - _ = try self.pushEntry(url, state, page, dispatch); + _ = try self.pushEntry(url, .{ .source = .navigation, .value = state }, page, dispatch); }, .traverse => |index| { self.index = index; @@ -132,7 +133,13 @@ pub fn processNavigation(self: *Navigation, page: *Page) !void { /// Pushes an entry into the Navigation stack WITHOUT actually navigating to it. /// For that, use `navigate`. -pub fn pushEntry(self: *Navigation, _url: []const u8, state: ?[]const u8, page: *Page, dispatch: bool) !*NavigationHistoryEntry { +pub fn pushEntry( + self: *Navigation, + _url: []const u8, + state: NavigationState, + page: *Page, + dispatch: bool, +) !*NavigationHistoryEntry { const arena = page.session.arena; const url = try arena.dupe(u8, _url); @@ -171,7 +178,13 @@ 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 { +pub fn replaceEntry( + self: *Navigation, + _url: []const u8, + state: NavigationState, + page: *Page, + dispatch: bool, +) !*NavigationHistoryEntry { const arena = page.session.arena; const url = try arena.dupe(u8, _url); @@ -242,7 +255,7 @@ pub fn navigate( // todo: Fire navigate event try finished.resolve({}); - _ = try self.pushEntry(url, state, page, true); + _ = try self.pushEntry(url, .{ .source = .navigation, .value = state }, page, true); } else { try page.navigateFromWebAPI(url, .{ .reason = .navigation }, kind); } @@ -290,7 +303,7 @@ pub fn _reload(self: *Navigation, _opts: ?ReloadOptions, page: *Page) !Navigatio const entry = self.currentEntry(); if (opts.state) |state| { const previous = entry; - entry.state = state.toJson(arena) catch return error.DataClone; + entry.state = .{ .source = .navigation, .value = state.toJson(arena) catch return error.DataClone }; NavigationCurrentEntryChangeEvent.dispatch(self, previous, .reload); } @@ -323,6 +336,6 @@ pub fn _updateCurrentEntry(self: *Navigation, options: UpdateCurrentEntryOptions const arena = page.session.arena; const previous = self.currentEntry(); - self.currentEntry().state = options.state.toJson(arena) catch return error.DataClone; + self.currentEntry().state = .{ .source = .navigation, .value = options.state.toJson(arena) catch return error.DataClone }; NavigationCurrentEntryChangeEvent.dispatch(self, previous, null); } diff --git a/src/browser/navigation/root.zig b/src/browser/navigation/root.zig index bfe5830f..14c5898c 100644 --- a/src/browser/navigation/root.zig +++ b/src/browser/navigation/root.zig @@ -56,6 +56,11 @@ pub const NavigationKind = union(NavigationType) { reload, }; +pub const NavigationState = struct { + source: enum { history, navigation }, + value: ?[]const u8, +}; + // https://developer.mozilla.org/en-US/docs/Web/API/NavigationHistoryEntry pub const NavigationHistoryEntry = struct { pub const prototype = *EventTarget; @@ -64,7 +69,7 @@ pub const NavigationHistoryEntry = struct { id: []const u8, key: []const u8, url: ?[]const u8, - state: ?[]const u8, + state: NavigationState, pub fn get_id(self: *const NavigationHistoryEntry) []const u8 { return self.id; @@ -95,12 +100,16 @@ pub const NavigationHistoryEntry = struct { return self.url; } - pub fn _getState(self: *const NavigationHistoryEntry, page: *Page) !?js.Value { - if (self.state) |state| { - return try js.Value.fromJson(page.js, state); - } else { - return null; + pub const StateReturn = union(enum) { value: ?js.Value, undefined: void }; + + pub fn _getState(self: *const NavigationHistoryEntry, page: *Page) !StateReturn { + if (self.state.source == .navigation) { + if (self.state.value) |value| { + return .{ .value = try js.Value.fromJson(page.js, value) }; + } } + + return .undefined; } };