diff --git a/src/browser/html/History.zig b/src/browser/html/History.zig
index 8931d7bb..308bfb1f 100644
--- a/src/browser/html/History.zig
+++ b/src/browser/html/History.zig
@@ -27,7 +27,8 @@ const History = @This();
const HistoryEntry = struct {
url: []const u8,
- // Serialized as JSON.
+ // This is serialized as JSON because
+ // History must survive a JsContext.
state: ?[]u8,
};
@@ -44,9 +45,13 @@ const ScrollRestorationMode = enum {
return null;
}
}
+
+ pub fn toString(self: ScrollRestorationMode) []const u8 {
+ return @tagName(self);
+ }
};
-scrollRestoration: ScrollRestorationMode = .auto,
+scroll_restoration: ScrollRestorationMode = .auto,
stack: std.ArrayListUnmanaged(HistoryEntry) = .empty,
current: ?usize = null,
@@ -54,15 +59,12 @@ pub fn get_length(self: *History) u32 {
return @intCast(self.stack.items.len);
}
-pub fn get_scrollRestoration(self: *History) []const u8 {
- return switch (self.scrollRestoration) {
- .auto => "auto",
- .manual => "manual",
- };
+pub fn get_scrollRestoration(self: *History) ScrollRestorationMode {
+ return self.scroll_restoration;
}
pub fn set_scrollRestoration(self: *History, mode: []const u8) void {
- self.scrollRestoration = ScrollRestorationMode.fromString(mode) orelse self.scrollRestoration;
+ self.scroll_restoration = ScrollRestorationMode.fromString(mode) orelse self.scroll_restoration;
}
pub fn get_state(self: *History, page: *Page) !?Env.Value {
@@ -102,23 +104,20 @@ pub fn dispatchPopStateEvent(state: ?[]const u8, page: *Page) void {
};
}
-fn _dispatchPopStateEvent(
- state: ?[]const u8,
- page: *Page,
-) !void {
+fn _dispatchPopStateEvent(state: ?[]const u8, page: *Page) !void {
var evt = try PopStateEvent.constructor("popstate", .{ .state = state });
_ = try parser.eventTargetDispatchEvent(
@as(*parser.EventTarget, @ptrCast(&page.window)),
- @as(*parser.Event, @ptrCast(&evt)),
+ &evt.proto,
);
}
pub fn _pushState(self: *History, state: Env.JsObject, _: ?[]const u8, _url: ?[]const u8, page: *Page) !void {
const arena = page.session.arena;
+ const json = try state.toJson(arena);
const url = if (_url) |u| try arena.dupe(u8, u) else try arena.dupe(u8, page.url.raw);
- const json = try state.toJson(page.session.arena);
const entry = HistoryEntry{ .state = json, .url = url };
try self.stack.append(arena, entry);
self.current = self.stack.items.len - 1;
@@ -129,8 +128,8 @@ pub fn _replaceState(self: *History, state: Env.JsObject, _: ?[]const u8, _url:
if (self.current) |curr| {
const entry = &self.stack.items[curr];
- const url = if (_url) |u| try arena.dupe(u8, u) else try arena.dupe(u8, page.url.raw);
const json = try state.toJson(arena);
+ const url = if (_url) |u| try arena.dupe(u8, u) else try arena.dupe(u8, page.url.raw);
entry.* = HistoryEntry{ .state = json, .url = url };
} else {
try self._pushState(state, "", _url, page);
@@ -152,11 +151,7 @@ pub fn go(self: *History, delta: i32, page: *Page) !void {
self.current = index;
if (try page.isSameOrigin(entry.url)) {
- if (entry.state) |state| {
- History.dispatchPopStateEvent(state, page);
- } else {
- History.dispatchPopStateEvent(null, page);
- }
+ History.dispatchPopStateEvent(entry.state, page);
}
try page.navigateFromWebAPI(entry.url, .{ .reason = .history });