mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-10-28 22:53:28 +00:00
functional history WebAPI
This commit is contained in:
@@ -25,9 +25,9 @@ const Page = @import("../page.zig").Page;
|
|||||||
const History = @This();
|
const History = @This();
|
||||||
|
|
||||||
const HistoryEntry = struct {
|
const HistoryEntry = struct {
|
||||||
url: ?[]const u8,
|
url: []const u8,
|
||||||
// Serialized Env.JsObject
|
// Serialized as JSON.
|
||||||
state: []u8,
|
state: ?[]u8,
|
||||||
};
|
};
|
||||||
|
|
||||||
const ScrollRestorationMode = enum {
|
const ScrollRestorationMode = enum {
|
||||||
@@ -64,52 +64,78 @@ pub fn set_scrollRestoration(self: *History, mode: []const u8) void {
|
|||||||
self.scrollRestoration = ScrollRestorationMode.fromString(mode) orelse self.scrollRestoration;
|
self.scrollRestoration = ScrollRestorationMode.fromString(mode) orelse self.scrollRestoration;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_state(self: *History, page: *Page) !?Env.JsObject {
|
pub fn get_state(self: *History, page: *Page) !?Env.Value {
|
||||||
if (self.current) |curr| {
|
if (self.current) |curr| {
|
||||||
const entry = self.stack.items[curr];
|
const entry = self.stack.items[curr];
|
||||||
const object = try Env.JsObject.fromJson(page.main_context, entry.state);
|
if (entry.state) |state| {
|
||||||
return object;
|
const value = try Env.Value.fromJson(page.main_context, state);
|
||||||
|
return value;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn _pushState(self: *History, state: Env.JsObject, _: ?[]const u8, url: ?[]const u8, page: *Page) !void {
|
pub fn pushNavigation(self: *History, _url: []const u8, page: *Page) !void {
|
||||||
const json = try state.toJson(page.arena);
|
const arena = page.session.arena;
|
||||||
|
const url = try arena.dupe(u8, _url);
|
||||||
|
|
||||||
|
const entry = HistoryEntry{ .state = null, .url = url };
|
||||||
|
try self.stack.append(arena, entry);
|
||||||
|
self.current = self.stack.items.len - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn _pushState(self: *History, state: Env.JsObject, _: ?[]const u8, _url: ?[]const u8, page: *Page) !void {
|
||||||
|
const arena = page.session.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 };
|
const entry = HistoryEntry{ .state = json, .url = url };
|
||||||
try self.stack.append(page.session.arena, entry);
|
try self.stack.append(arena, entry);
|
||||||
self.current = self.stack.items.len;
|
self.current = self.stack.items.len - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO implement the function
|
pub fn _replaceState(self: *History, state: Env.JsObject, _: ?[]const u8, _url: ?[]const u8, page: *Page) !void {
|
||||||
// data must handle any argument. We could expect a std.json.Value but
|
const arena = page.session.arena;
|
||||||
// https://github.com/lightpanda-io/zig-js-runtime/issues/267 is missing.
|
|
||||||
pub fn _replaceState(self: *History, state: Env.JsObject, _: ?[]const u8, url: ?[]const u8) void {
|
|
||||||
_ = self;
|
|
||||||
_ = url;
|
|
||||||
_ = state;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO implement the function
|
|
||||||
pub fn _go(self: *History, delta: ?i32) void {
|
|
||||||
_ = self;
|
|
||||||
_ = delta;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn _back(self: *History) void {
|
|
||||||
if (self.current) |curr| {
|
if (self.current) |curr| {
|
||||||
if (curr > 0) {
|
const entry = &self.stack.items[curr];
|
||||||
self.current = curr - 1;
|
const url = if (_url) |u| try arena.dupe(u8, u) else try arena.dupe(u8, page.url.raw);
|
||||||
}
|
const json = try state.toJson(arena);
|
||||||
|
entry.* = HistoryEntry{ .state = json, .url = url };
|
||||||
|
} else {
|
||||||
|
try self._pushState(state, "", _url, page);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn _forward(self: *History) void {
|
pub fn go(self: *History, delta: i32, page: *Page) !void {
|
||||||
if (self.current) |curr| {
|
// 0 behaves the same as no argument, both reloading the page.
|
||||||
if (curr < self.stack.items.len) {
|
// If this is getting called, there SHOULD be an entry, atleast from pushNavigation.
|
||||||
self.current = curr + 1;
|
const current = self.current.?;
|
||||||
}
|
|
||||||
|
const index_s: i64 = @intCast(@as(i64, @intCast(current)) + @as(i64, @intCast(delta)));
|
||||||
|
if (index_s < 0 or index_s > self.stack.items.len - 1) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const index = @as(usize, @intCast(index_s));
|
||||||
|
const entry = self.stack.items[index];
|
||||||
|
self.current = index;
|
||||||
|
try page.navigateFromWebAPI(entry.url, .{ .reason = .history });
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn _go(self: *History, _delta: ?i32, page: *Page) !void {
|
||||||
|
try self.go(_delta orelse 0, page);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn _back(self: *History, page: *Page) !void {
|
||||||
|
try self.go(-1, page);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn _forward(self: *History, page: *Page) !void {
|
||||||
|
try self.go(1, page);
|
||||||
}
|
}
|
||||||
|
|
||||||
const testing = @import("../../testing.zig");
|
const testing = @import("../../testing.zig");
|
||||||
|
|||||||
@@ -806,6 +806,9 @@ pub const Page = struct {
|
|||||||
unreachable;
|
unreachable;
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Push the navigation after a successful load.
|
||||||
|
try self.session.history.pushNavigation(self.url.raw, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pageErrorCallback(ctx: *anyopaque, err: anyerror) void {
|
fn pageErrorCallback(ctx: *anyopaque, err: anyerror) void {
|
||||||
@@ -1136,6 +1139,7 @@ pub const NavigateReason = enum {
|
|||||||
address_bar,
|
address_bar,
|
||||||
form,
|
form,
|
||||||
script,
|
script,
|
||||||
|
history,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const NavigateOpts = struct {
|
pub const NavigateOpts = struct {
|
||||||
|
|||||||
@@ -174,7 +174,7 @@ pub fn pageNavigate(arena: Allocator, bc: anytype, event: *const Notification.Pa
|
|||||||
var cdp = bc.cdp;
|
var cdp = bc.cdp;
|
||||||
const reason_: ?[]const u8 = switch (event.opts.reason) {
|
const reason_: ?[]const u8 = switch (event.opts.reason) {
|
||||||
.anchor => "anchorClick",
|
.anchor => "anchorClick",
|
||||||
.script => "scriptInitiated",
|
.script, .history => "scriptInitiated",
|
||||||
.form => switch (event.opts.method) {
|
.form => switch (event.opts.method) {
|
||||||
.GET => "formSubmissionGet",
|
.GET => "formSubmissionGet",
|
||||||
.POST => "formSubmissionPost",
|
.POST => "formSubmissionPost",
|
||||||
|
|||||||
Reference in New Issue
Block a user