@@ -25,9 +25,9 @@ const Page = @import("../page.zig").Page;
2525const History = @This ();
2626
2727const HistoryEntry = struct {
28- url : ? []const u8 ,
29- // Serialized Env.JsObject
30- state : []u8 ,
28+ url : []const u8 ,
29+ // Serialized as JSON.
30+ state : ? []u8 ,
3131};
3232
3333const ScrollRestorationMode = enum {
@@ -64,52 +64,78 @@ pub fn set_scrollRestoration(self: *History, mode: []const u8) void {
6464 self .scrollRestoration = ScrollRestorationMode .fromString (mode ) orelse self .scrollRestoration ;
6565}
6666
67- pub fn get_state (self : * History , page : * Page ) ! ? Env.JsObject {
67+ pub fn get_state (self : * History , page : * Page ) ! ? Env.Value {
6868 if (self .current ) | curr | {
6969 const entry = self .stack .items [curr ];
70- const object = try Env .JsObject .fromJson (page .main_context , entry .state );
71- return object ;
70+ if (entry .state ) | state | {
71+ const value = try Env .Value .fromJson (page .main_context , state );
72+ return value ;
73+ } else {
74+ return null ;
75+ }
7276 } else {
7377 return null ;
7478 }
7579}
7680
77- pub fn _pushState (self : * History , state : Env.JsObject , _ : ? []const u8 , url : ? []const u8 , page : * Page ) ! void {
78- const json = try state .toJson (page .arena );
79- const entry = HistoryEntry { .state = json , .url = url };
80- try self .stack .append (page .session .arena , entry );
81- self .current = self .stack .items .len ;
82- }
81+ pub fn pushNavigation (self : * History , _url : []const u8 , page : * Page ) ! void {
82+ const arena = page .session .arena ;
83+ const url = try arena .dupe (u8 , _url );
8384
84- // TODO implement the function
85- // data must handle any argument. We could expect a std.json.Value but
86- // https://github.com/lightpanda-io/zig-js-runtime/issues/267 is missing.
87- pub fn _replaceState (self : * History , state : Env.JsObject , _ : ? []const u8 , url : ? []const u8 ) void {
88- _ = self ;
89- _ = url ;
90- _ = state ;
85+ const entry = HistoryEntry { .state = null , .url = url };
86+ try self .stack .append (arena , entry );
87+ self .current = self .stack .items .len - 1 ;
9188}
9289
93- // TODO implement the function
94- pub fn _go (self : * History , delta : ? i32 ) void {
95- _ = self ;
96- _ = delta ;
90+ pub fn _pushState (self : * History , state : Env.JsObject , _ : ? []const u8 , _url : ? []const u8 , page : * Page ) ! void {
91+ const arena = page .session .arena ;
92+
93+ const url = if (_url ) | u | try arena .dupe (u8 , u ) else try arena .dupe (u8 , page .url .raw );
94+ const json = try state .toJson (page .session .arena );
95+ const entry = HistoryEntry { .state = json , .url = url };
96+ try self .stack .append (arena , entry );
97+ self .current = self .stack .items .len - 1 ;
9798}
9899
99- pub fn _back (self : * History ) void {
100+ pub fn _replaceState (self : * History , state : Env.JsObject , _ : ? []const u8 , _url : ? []const u8 , page : * Page ) ! void {
101+ const arena = page .session .arena ;
102+
100103 if (self .current ) | curr | {
101- if (curr > 0 ) {
102- self .current = curr - 1 ;
103- }
104+ const entry = & self .stack .items [curr ];
105+ const url = if (_url ) | u | try arena .dupe (u8 , u ) else try arena .dupe (u8 , page .url .raw );
106+ const json = try state .toJson (arena );
107+ entry .* = HistoryEntry { .state = json , .url = url };
108+ } else {
109+ try self ._pushState (state , "" , _url , page );
104110 }
105111}
106112
107- pub fn _forward (self : * History ) void {
108- if (self .current ) | curr | {
109- if (curr < self .stack .items .len ) {
110- self .current = curr + 1 ;
111- }
113+ pub fn go (self : * History , delta : i32 , page : * Page ) ! void {
114+ // 0 behaves the same as no argument, both reloading the page.
115+ // If this is getting called, there SHOULD be an entry, atleast from pushNavigation.
116+ const current = self .current .? ;
117+
118+ const index_s : i64 = @intCast (@as (i64 , @intCast (current )) + @as (i64 , @intCast (delta )));
119+ if (index_s < 0 or index_s > self .stack .items .len - 1 ) {
120+ return ;
112121 }
122+
123+ const index = @as (usize , @intCast (index_s ));
124+ const entry = self .stack .items [index ];
125+ self .current = index ;
126+ try page .navigateFromWebAPI (entry .url , .{ .reason = .history });
127+ }
128+
129+ pub fn _go (self : * History , _delta : ? i32 , page : * Page ) ! void {
130+ try self .go (_delta orelse 0 , page );
131+ }
132+
133+ pub fn _back (self : * History , page : * Page ) ! void {
134+ try self .go (-1 , page );
135+ }
136+
137+ pub fn _forward (self : * History , page : * Page ) ! void {
138+ try self .go (1 , page );
113139}
114140
115141const testing = @import ("../../testing.zig" );
0 commit comments