mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-03-29 08:00:05 +00:00
Compare commits
2 Commits
v0.1
...
navigate-e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cb141c35b7 | ||
|
|
01c2f2c6ea |
@@ -40,6 +40,7 @@ const MessageEvent = @import("../dom/MessageChannel.zig").MessageEvent;
|
||||
const PopStateEvent = @import("../html/History.zig").PopStateEvent;
|
||||
const CompositionEvent = @import("composition_event.zig").CompositionEvent;
|
||||
const NavigationCurrentEntryChangeEvent = @import("../navigation/root.zig").NavigationCurrentEntryChangeEvent;
|
||||
const NavigateEvent = @import("../navigation/root.zig").NavigateEvent;
|
||||
|
||||
// Event interfaces
|
||||
pub const Interfaces = .{
|
||||
@@ -53,6 +54,7 @@ pub const Interfaces = .{
|
||||
PopStateEvent,
|
||||
CompositionEvent,
|
||||
NavigationCurrentEntryChangeEvent,
|
||||
NavigateEvent,
|
||||
};
|
||||
|
||||
pub const Union = generate.Union(Interfaces);
|
||||
@@ -85,6 +87,7 @@ pub const Event = struct {
|
||||
.navigation_current_entry_change_event => .{
|
||||
.NavigationCurrentEntryChangeEvent = @as(*NavigationCurrentEntryChangeEvent, @ptrCast(evt)).*,
|
||||
},
|
||||
.navigate_event => .{ .NavigateEvent = @as(*NavigateEvent, @ptrCast(evt)).* },
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -208,6 +208,138 @@ pub const NavigationCurrentEntryChangeEvent = struct {
|
||||
}
|
||||
};
|
||||
|
||||
pub const NavigateEvent = struct {
|
||||
pub const prototype = *Event;
|
||||
pub const union_make_copy = true;
|
||||
|
||||
pub const EventInit = struct {
|
||||
canIntercept: ?bool = false,
|
||||
// todo: destination
|
||||
downloadRequest: ?[]const u8 = null,
|
||||
// todo: formData
|
||||
hashChange: ?bool = false,
|
||||
hasUAVisualTransition: ?bool = false,
|
||||
// info: ?js.Value,
|
||||
navigationType: ?NavigationType = .push,
|
||||
// todo: signal
|
||||
// todo: sourceElement
|
||||
userInitiated: ?bool = false,
|
||||
};
|
||||
|
||||
proto: parser.Event,
|
||||
can_intercept: bool,
|
||||
download_request: ?[]const u8,
|
||||
// todo: desintation
|
||||
hash_change: bool,
|
||||
has_ua_visual_transition: bool,
|
||||
info: []const u8,
|
||||
navigation_type: NavigationType,
|
||||
// todo: signal
|
||||
// todo: sourceElement
|
||||
user_initiated: bool,
|
||||
|
||||
pub fn constructor(event_type: []const u8, opts: EventInit) !NavigateEvent {
|
||||
const event = try parser.eventCreate();
|
||||
defer parser.eventDestroy(event);
|
||||
|
||||
try parser.eventInit(event, event_type, .{});
|
||||
parser.eventSetInternalType(event, .navigate_event);
|
||||
|
||||
return .{
|
||||
.proto = event.*,
|
||||
.can_intercept = opts.canIntercept orelse false,
|
||||
.download_request = opts.downloadRequest orelse null,
|
||||
.hash_change = opts.hashChange orelse false,
|
||||
.has_ua_visual_transition = opts.hasUAVisualTransition orelse false,
|
||||
.info = undefined,
|
||||
.navigation_type = opts.navigationType orelse .push,
|
||||
// .info = if (opts.info) |info| try info.toString(page.arena) else null,
|
||||
.user_initiated = opts.userInitiated orelse false,
|
||||
};
|
||||
}
|
||||
|
||||
pub const InterceptOptions = struct {
|
||||
// runs after currentEntry is updated
|
||||
handler: ?js.Function,
|
||||
// runs before currentEntry is updated
|
||||
precommitHandler: ?js.Function,
|
||||
focusReset: ?enum { @"after-transition", manual },
|
||||
scroll: ?enum { @"after-transition", manual },
|
||||
};
|
||||
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/NavigateEvent/intercept
|
||||
pub fn intercept(
|
||||
self: *NavigateEvent,
|
||||
opts: ?InterceptOptions,
|
||||
_: *Page,
|
||||
) !void {
|
||||
if (!self.can_intercept) {
|
||||
return error.Security;
|
||||
}
|
||||
|
||||
if (self.proto.in_dispatch) {
|
||||
return error.InvalidState;
|
||||
}
|
||||
|
||||
// try parser.eventPreventDefault(&self.proto);
|
||||
|
||||
if (opts) |options| {
|
||||
if (options.precommitHandler) |handler| {
|
||||
_ = try handler.call(void, .{});
|
||||
}
|
||||
}
|
||||
|
||||
// update current entry here.
|
||||
|
||||
if (opts) |options| {
|
||||
if (options.handler) |handler| {
|
||||
const result = try handler.call(js.Value, .{});
|
||||
|
||||
if (result.value.isPromise()) {
|
||||
// must be stored and resolved based on nav outcome.
|
||||
}
|
||||
}
|
||||
|
||||
// todo: handle focusReset and scroll
|
||||
}
|
||||
}
|
||||
|
||||
pub fn scroll(self: *NavigateEvent) !void {
|
||||
_ = self;
|
||||
}
|
||||
|
||||
pub fn dispatch(navigation: *Navigation, from: *NavigationHistoryEntry, typ: ?NavigationType) void {
|
||||
log.debug(.script_event, "dispatch event", .{
|
||||
.type = "navigate",
|
||||
.source = "navigation",
|
||||
});
|
||||
|
||||
var evt = NavigateEvent.constructor(
|
||||
"navigate",
|
||||
.{ .from = from, .navigationType = typ },
|
||||
) catch |err| {
|
||||
log.err(.app, "event constructor error", .{
|
||||
.err = err,
|
||||
.type = "navigate",
|
||||
.source = "navigation",
|
||||
});
|
||||
|
||||
return;
|
||||
};
|
||||
|
||||
_ = parser.eventTargetDispatchEvent(
|
||||
@as(*parser.EventTarget, @ptrCast(navigation)),
|
||||
&evt.proto,
|
||||
) catch |err| {
|
||||
log.err(.app, "dispatch event error", .{
|
||||
.err = err,
|
||||
.type = "navigate",
|
||||
.source = "navigation",
|
||||
});
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const testing = @import("../../testing.zig");
|
||||
test "Browser: Navigation" {
|
||||
try testing.htmlRunner("html/navigation/navigation.html");
|
||||
|
||||
@@ -561,6 +561,7 @@ pub const EventType = enum(u8) {
|
||||
pop_state = 9,
|
||||
composition_event = 10,
|
||||
navigation_current_entry_change_event = 11,
|
||||
navigate_event = 12,
|
||||
};
|
||||
|
||||
pub const MutationEvent = c.dom_mutation_event;
|
||||
|
||||
Reference in New Issue
Block a user