@@ -25,71 +25,36 @@ 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 {
29+ pub const ENUM_JS_USE_TAG = true ;
30+
3631 auto ,
3732 manual ,
38-
39- pub fn fromString (str : []const u8 ) ? ScrollRestorationMode {
40- for (std .enums .values (ScrollRestorationMode )) | mode | {
41- if (std .ascii .eqlIgnoreCase (str , @tagName (mode ))) {
42- return mode ;
43- }
44- } else {
45- return null ;
46- }
47- }
48-
49- pub fn toString (self : ScrollRestorationMode ) []const u8 {
50- return @tagName (self );
51- }
5233};
5334
5435scroll_restoration : ScrollRestorationMode = .auto ,
55- stack : std .ArrayListUnmanaged (HistoryEntry ) = .empty ,
56- current : ? usize = null ,
5736
58- pub fn get_length (self : * History ) u32 {
59- return @intCast (self . stack .items .len );
37+ pub fn get_length (_ : * History , page : * Page ) u32 {
38+ return @intCast (page . session . navigation . entries .items .len );
6039}
6140
6241pub fn get_scrollRestoration (self : * History ) ScrollRestorationMode {
6342 return self .scroll_restoration ;
6443}
6544
66- pub fn set_scrollRestoration (self : * History , mode : [] const u8 ) void {
67- self .scroll_restoration = ScrollRestorationMode . fromString ( mode ) orelse self . scroll_restoration ;
45+ pub fn set_scrollRestoration (self : * History , mode : ScrollRestorationMode ) void {
46+ self .scroll_restoration = mode ;
6847}
6948
70- pub fn get_state (self : * History , page : * Page ) ! ? js.Value {
71- if (self .current ) | curr | {
72- const entry = self .stack .items [curr ];
73- if (entry .state ) | state | {
74- const value = try js .Value .fromJson (page .js , state );
75- return value ;
76- } else {
77- return null ;
78- }
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 ;
7953 } else {
8054 return null ;
8155 }
8256}
8357
84- pub fn pushNavigation (self : * History , _url : []const u8 , page : * Page ) ! void {
85- const arena = page .session .arena ;
86- const url = try arena .dupe (u8 , _url );
87-
88- const entry = HistoryEntry { .state = null , .url = url };
89- try self .stack .append (arena , entry );
90- self .current = self .stack .items .len - 1 ;
91- }
92-
9358pub fn dispatchPopStateEvent (state : ? []const u8 , page : * Page ) void {
9459 log .debug (.script_event , "dispatch popstate event" , .{
9560 .type = "popstate" ,
@@ -113,48 +78,42 @@ fn _dispatchPopStateEvent(state: ?[]const u8, page: *Page) !void {
11378 );
11479}
11580
116- 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 {
11782 const arena = page .session .arena ;
118-
119- const json = try state .toJson (arena );
12083 const url = if (_url ) | u | try arena .dupe (u8 , u ) else try arena .dupe (u8 , page .url .raw );
121- const entry = HistoryEntry { .state = json , .url = url };
122- try self .stack .append (arena , entry );
123- self .current = self .stack .items .len - 1 ;
84+ _ = try page .session .navigation .pushEntry (url , .{ .state = state }, page );
12485}
12586
126- 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 {
12788 const arena = page .session .arena ;
12889
129- if (self .current ) | curr | {
130- const entry = & self .stack .items [curr ];
131- const json = try state .toJson (arena );
132- const url = if (_url ) | u | try arena .dupe (u8 , u ) else try arena .dupe (u8 , page .url .raw );
133- entry .* = HistoryEntry { .state = json , .url = url };
134- } else {
135- try self ._pushState (state , "" , _url , page );
136- }
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 ;
13796}
13897
139- pub fn go (self : * History , delta : i32 , page : * Page ) ! void {
98+ pub fn go (_ : * const History , delta : i32 , page : * Page ) ! void {
14099 // 0 behaves the same as no argument, both reloading the page.
141- // If this is getting called, there SHOULD be an entry, atleast from pushNavigation.
142- const current = self .current .? ;
143100
101+ const current = page .session .navigation .index ;
144102 const index_s : i64 = @intCast (@as (i64 , @intCast (current )) + @as (i64 , @intCast (delta )));
145- 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 ) {
146104 return ;
147105 }
148106
149107 const index = @as (usize , @intCast (index_s ));
150- const entry = self .stack .items [index ];
151- self .current = index ;
108+ const entry = page .session .navigation .entries .items [index ];
152109
153- if (try page .isSameOrigin (entry .url )) {
154- History .dispatchPopStateEvent (entry .state , page );
110+ if (entry .url ) | url | {
111+ if (try page .isSameOrigin (url )) {
112+ History .dispatchPopStateEvent (entry .state , page );
113+ }
155114 }
156115
157- try page . navigateFromWebAPI ( entry .url , .{ . reason = .history } );
116+ _ = try entry .navigate ( page , .force );
158117}
159118
160119pub fn _go (self : * History , _delta : ? i32 , page : * Page ) ! void {
0 commit comments