@@ -25,13 +25,6 @@ const Page = @import("../page.zig").Page;
2525// https://html.spec.whatwg.org/multipage/nav-history-apis.html#the-history-interface
2626const History = @This ();
2727
28- const HistoryEntry = struct {
29- url : []const u8 ,
30- // This is serialized as JSON because
31- // History must survive a JsContext.
32- state : ? []u8 ,
33- };
34-
3528const ScrollRestorationMode = enum {
3629 pub const ENUM_JS_USE_TAG = true ;
3730
@@ -40,11 +33,9 @@ const ScrollRestorationMode = enum {
4033};
4134
4235scroll_restoration : ScrollRestorationMode = .auto ,
43- stack : std .ArrayListUnmanaged (HistoryEntry ) = .empty ,
44- current : ? usize = null ,
4536
46- pub fn get_length (self : * History ) u32 {
47- return @intCast (self . stack .items .len );
37+ pub fn get_length (_ : * History , page : * Page ) u32 {
38+ return @intCast (page . session . navigation . entries .items .len );
4839}
4940
5041pub fn get_scrollRestoration (self : * History ) ScrollRestorationMode {
@@ -55,29 +46,15 @@ pub fn set_scrollRestoration(self: *History, mode: ScrollRestorationMode) void {
5546 self .scroll_restoration = mode ;
5647}
5748
58- pub fn get_state (self : * History , page : * Page ) ! ? js.Value {
59- if (self .current ) | curr | {
60- const entry = self .stack .items [curr ];
61- if (entry .state ) | state | {
62- const value = try js .Value .fromJson (page .js , state );
63- return value ;
64- } else {
65- return null ;
66- }
49+ pub fn get_state (_ : * History , page : * Page ) ! ? js.Value {
50+ if (page .session .navigation .currentEntry ().state ) | state | {
51+ const value = try js .Value .fromJson (page .js , state );
52+ return value ;
6753 } else {
6854 return null ;
6955 }
7056}
7157
72- pub fn pushNavigation (self : * History , _url : []const u8 , page : * Page ) ! void {
73- const arena = page .session .arena ;
74- const url = try arena .dupe (u8 , _url );
75-
76- const entry = HistoryEntry { .state = null , .url = url };
77- try self .stack .append (arena , entry );
78- self .current = self .stack .items .len - 1 ;
79- }
80-
8158pub fn dispatchPopStateEvent (state : ? []const u8 , page : * Page ) void {
8259 log .debug (.script_event , "dispatch popstate event" , .{
8360 .type = "popstate" ,
@@ -101,48 +78,42 @@ fn _dispatchPopStateEvent(state: ?[]const u8, page: *Page) !void {
10178 );
10279}
10380
104- pub fn _pushState (self : * History , state : js.Object , _ : ? []const u8 , _url : ? []const u8 , page : * Page ) ! void {
81+ pub fn _pushState (_ : * const History , state : js.Object , _ : ? []const u8 , _url : ? []const u8 , page : * Page ) ! void {
10582 const arena = page .session .arena ;
106-
107- const json = try state .toJson (arena );
10883 const url = if (_url ) | u | try arena .dupe (u8 , u ) else try arena .dupe (u8 , page .url .raw );
109- const entry = HistoryEntry { .state = json , .url = url };
110- try self .stack .append (arena , entry );
111- self .current = self .stack .items .len - 1 ;
84+ _ = try page .session .navigation .pushEntry (url , .{ .state = state }, page );
11285}
11386
114- pub fn _replaceState (self : * History , state : js.Object , _ : ? []const u8 , _url : ? []const u8 , page : * Page ) ! void {
87+ pub fn _replaceState (_ : * const History , state : js.Object , _ : ? []const u8 , _url : ? []const u8 , page : * Page ) ! void {
11588 const arena = page .session .arena ;
11689
117- if (self .current ) | curr | {
118- const entry = & self .stack .items [curr ];
119- const json = try state .toJson (arena );
120- const url = if (_url ) | u | try arena .dupe (u8 , u ) else try arena .dupe (u8 , page .url .raw );
121- entry .* = HistoryEntry { .state = json , .url = url };
122- } else {
123- try self ._pushState (state , "" , _url , page );
124- }
90+ const entry = page .session .navigation .currentEntry ();
91+ const json = try state .toJson (arena );
92+ const url = if (_url ) | u | try arena .dupe (u8 , u ) else try arena .dupe (u8 , page .url .raw );
93+
94+ entry .state = json ;
95+ entry .url = url ;
12596}
12697
127- pub fn go (self : * History , delta : i32 , page : * Page ) ! void {
98+ pub fn go (_ : * const History , delta : i32 , page : * Page ) ! void {
12899 // 0 behaves the same as no argument, both reloading the page.
129- // If this is getting called, there SHOULD be an entry, atleast from pushNavigation.
130- const current = self .current .? ;
131100
101+ const current = page .session .navigation .index ;
132102 const index_s : i64 = @intCast (@as (i64 , @intCast (current )) + @as (i64 , @intCast (delta )));
133- if (index_s < 0 or index_s > self . stack .items .len - 1 ) {
103+ if (index_s < 0 or index_s > page . session . navigation . entries .items .len - 1 ) {
134104 return ;
135105 }
136106
137107 const index = @as (usize , @intCast (index_s ));
138- const entry = self .stack .items [index ];
139- self .current = index ;
108+ const entry = page .session .navigation .entries .items [index ];
140109
141- if (try page .isSameOrigin (entry .url )) {
142- History .dispatchPopStateEvent (entry .state , page );
110+ if (entry .url ) | url | {
111+ if (try page .isSameOrigin (url )) {
112+ History .dispatchPopStateEvent (entry .state , page );
113+ }
143114 }
144115
145- try page . navigateFromWebAPI ( entry .url , .{ . reason = .history } );
116+ _ = try entry .navigate ( page , .force );
146117}
147118
148119pub fn _go (self : * History , _delta : ? i32 , page : * Page ) ! void {
0 commit comments