diff --git a/src/browser/events/PageTransitionEvent.zig b/src/browser/events/PageTransitionEvent.zig new file mode 100644 index 00000000..d963a356 --- /dev/null +++ b/src/browser/events/PageTransitionEvent.zig @@ -0,0 +1,84 @@ +// Copyright (C) 2023-2024 Lightpanda (Selecy SAS) +// +// Francis Bouvier +// Pierre Tachoire +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +const log = @import("../../log.zig"); +const Window = @import("../html/window.zig").Window; + +const parser = @import("../netsurf.zig"); +const Event = @import("../events/event.zig").Event; + +// https://developer.mozilla.org/en-US/docs/Web/API/PageTransitionEvent +const PageTransitionEvent = @This(); + +pub const prototype = *Event; +pub const union_make_copy = true; + +pub const EventInit = struct { + persisted: ?bool, +}; + +proto: parser.Event, +persisted: bool, + +pub fn constructor(event_type: []const u8, opts: EventInit) !PageTransitionEvent { + const event = try parser.eventCreate(); + defer parser.eventDestroy(event); + + try parser.eventInit(event, event_type, .{}); + parser.eventSetInternalType(event, .page_transition_event); + + return .{ + .proto = event.*, + .persisted = opts.persisted orelse false, + }; +} + +const PageTransitionKind = enum { show, hide }; + +pub fn dispatch(window: *Window, kind: PageTransitionKind, persisted: bool) void { + const evt_type = switch (kind) { + .show => "pageshow", + .hide => "pagehide", + }; + + log.debug(.script_event, "dispatch event", .{ + .type = evt_type, + .source = "navigation", + }); + + var evt = PageTransitionEvent.constructor(evt_type, .{ .persisted = persisted }) catch |err| { + log.err(.app, "event constructor error", .{ + .err = err, + .type = evt_type, + .source = "navigation", + }); + + return; + }; + + _ = parser.eventTargetDispatchEvent( + @as(*parser.EventTarget, @ptrCast(window)), + &evt.proto, + ) catch |err| { + log.err(.app, "dispatch event error", .{ + .err = err, + .type = evt_type, + .source = "navigation", + }); + }; +} diff --git a/src/browser/events/event.zig b/src/browser/events/event.zig index 1769ebf0..c2636007 100644 --- a/src/browser/events/event.zig +++ b/src/browser/events/event.zig @@ -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 PageTransitionEvent = @import("../events/PageTransitionEvent.zig"); // Event interfaces pub const Interfaces = .{ @@ -53,6 +54,7 @@ pub const Interfaces = .{ PopStateEvent, CompositionEvent, NavigationCurrentEntryChangeEvent, + PageTransitionEvent, }; pub const Union = generate.Union(Interfaces); @@ -85,6 +87,7 @@ pub const Event = struct { .navigation_current_entry_change_event => .{ .NavigationCurrentEntryChangeEvent = @as(*NavigationCurrentEntryChangeEvent, @ptrCast(evt)).*, }, + .page_transition_event => .{ .PageTransitionEvent = @as(*PageTransitionEvent, @ptrCast(evt)).* }, }; } diff --git a/src/browser/netsurf.zig b/src/browser/netsurf.zig index a08a6996..8d0dbf69 100644 --- a/src/browser/netsurf.zig +++ b/src/browser/netsurf.zig @@ -561,6 +561,7 @@ pub const EventType = enum(u8) { pop_state = 9, composition_event = 10, navigation_current_entry_change_event = 11, + page_transition_event = 12, }; pub const MutationEvent = c.dom_mutation_event;