mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-12-14 15:28:57 +00:00
Merge pull request #1271 from lightpanda-io/zigdom-event-opts-inherit
Inherit Prototype Event Options
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
|
||||
const std = @import("std");
|
||||
const js = @import("../js/js.zig");
|
||||
const reflect = @import("../reflect.zig");
|
||||
|
||||
const Page = @import("../Page.zig");
|
||||
const EventTarget = @import("EventTarget.zig");
|
||||
@@ -195,6 +196,54 @@ pub fn composedPath(self: *Event, page: *Page) ![]const *EventTarget {
|
||||
return path;
|
||||
}
|
||||
|
||||
pub fn populateFromOptions(self: *Event, opts: anytype) void {
|
||||
self._bubbles = opts.bubbles;
|
||||
self._cancelable = opts.cancelable;
|
||||
self._composed = opts.composed;
|
||||
}
|
||||
|
||||
pub fn inheritOptions(comptime T: type, comptime additions: anytype) type {
|
||||
var all_fields: []const std.builtin.Type.StructField = &.{};
|
||||
|
||||
if (@hasField(T, "_proto")) {
|
||||
const t_fields = @typeInfo(T).@"struct".fields;
|
||||
|
||||
inline for (t_fields) |field| {
|
||||
if (std.mem.eql(u8, field.name, "_proto")) {
|
||||
const ProtoType = reflect.Struct(field.type);
|
||||
if (@hasDecl(ProtoType, "Options")) {
|
||||
const parent_options = @typeInfo(ProtoType.Options);
|
||||
all_fields = all_fields ++ parent_options.@"struct".fields;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const additions_info = @typeInfo(additions);
|
||||
all_fields = all_fields ++ additions_info.@"struct".fields;
|
||||
|
||||
return @Type(.{
|
||||
.@"struct" = .{
|
||||
.layout = .auto,
|
||||
.fields = all_fields,
|
||||
.decls = &.{},
|
||||
.is_tuple = false,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
pub fn populatePrototypes(self: anytype, opts: anytype) void {
|
||||
const T = @TypeOf(self.*);
|
||||
|
||||
if (@hasField(T, "_proto")) {
|
||||
populatePrototypes(self._proto, opts);
|
||||
}
|
||||
|
||||
if (@hasDecl(T, "populateFromOptions")) {
|
||||
T.populateFromOptions(self, opts);
|
||||
}
|
||||
}
|
||||
|
||||
pub const JsApi = struct {
|
||||
pub const bridge = js.Bridge(Event);
|
||||
|
||||
|
||||
@@ -26,23 +26,21 @@ const CompositionEvent = @This();
|
||||
_proto: *Event,
|
||||
_data: []const u8 = "",
|
||||
|
||||
pub const InitOptions = struct {
|
||||
const CompositionEventOptions = struct {
|
||||
data: ?[]const u8 = null,
|
||||
bubbles: bool = false,
|
||||
cancelable: bool = false,
|
||||
};
|
||||
|
||||
pub fn init(typ: []const u8, opts_: ?InitOptions, page: *Page) !*CompositionEvent {
|
||||
const opts = opts_ orelse InitOptions{};
|
||||
const Options = Event.inheritOptions(CompositionEvent, CompositionEventOptions);
|
||||
|
||||
pub fn init(typ: []const u8, opts_: ?Options, page: *Page) !*CompositionEvent {
|
||||
const opts = opts_ orelse Options{};
|
||||
|
||||
const event = try page._factory.event(typ, CompositionEvent{
|
||||
._proto = undefined,
|
||||
._data = if (opts.data) |str| try page.dupeString(str) else "",
|
||||
});
|
||||
|
||||
event._proto._bubbles = opts.bubbles;
|
||||
event._proto._cancelable = opts.cancelable;
|
||||
|
||||
Event.populatePrototypes(event, opts);
|
||||
return event;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,25 +29,26 @@ _proto: *Event,
|
||||
_detail: ?js.Object = null,
|
||||
_arena: Allocator,
|
||||
|
||||
pub const InitOptions = struct {
|
||||
const CustomEventOptions = struct {
|
||||
detail: ?js.Object = null,
|
||||
bubbles: bool = false,
|
||||
cancelable: bool = false,
|
||||
};
|
||||
|
||||
pub fn init(typ: []const u8, opts_: ?InitOptions, page: *Page) !*CustomEvent {
|
||||
const Options = Event.inheritOptions(CustomEvent, CustomEventOptions);
|
||||
|
||||
pub fn init(typ: []const u8, opts_: ?Options, page: *Page) !*CustomEvent {
|
||||
const arena = page.arena;
|
||||
const opts = opts_ orelse InitOptions{};
|
||||
const opts = opts_ orelse Options{};
|
||||
|
||||
const event = try page._factory.event(typ, CustomEvent{
|
||||
._arena = arena,
|
||||
._proto = undefined,
|
||||
._detail = if (opts.detail) |detail| try detail.persist() else null,
|
||||
});
|
||||
|
||||
event._proto._bubbles = opts.bubbles;
|
||||
event._proto._cancelable = opts.cancelable;
|
||||
const event = try page._factory.event(
|
||||
typ,
|
||||
CustomEvent{
|
||||
._arena = arena,
|
||||
._proto = undefined,
|
||||
._detail = if (opts.detail) |detail| try detail.persist() else null,
|
||||
},
|
||||
);
|
||||
|
||||
Event.populatePrototypes(event, opts);
|
||||
return event;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,33 +33,34 @@ _column_number: u32 = 0,
|
||||
_error: ?js.Object = null,
|
||||
_arena: Allocator,
|
||||
|
||||
pub const InitOptions = struct {
|
||||
pub const ErrorEventOptions = struct {
|
||||
message: ?[]const u8 = null,
|
||||
filename: ?[]const u8 = null,
|
||||
lineno: u32 = 0,
|
||||
colno: u32 = 0,
|
||||
@"error": ?js.Object = null,
|
||||
bubbles: bool = false,
|
||||
cancelable: bool = false,
|
||||
};
|
||||
|
||||
pub fn init(typ: []const u8, opts_: ?InitOptions, page: *Page) !*ErrorEvent {
|
||||
const Options = Event.inheritOptions(ErrorEvent, ErrorEventOptions);
|
||||
|
||||
pub fn init(typ: []const u8, opts_: ?Options, page: *Page) !*ErrorEvent {
|
||||
const arena = page.arena;
|
||||
const opts = opts_ orelse InitOptions{};
|
||||
const opts = opts_ orelse Options{};
|
||||
|
||||
const event = try page._factory.event(typ, ErrorEvent{
|
||||
._arena = arena,
|
||||
._proto = undefined,
|
||||
._message = if (opts.message) |str| try arena.dupe(u8, str) else "",
|
||||
._filename = if (opts.filename) |str| try arena.dupe(u8, str) else "",
|
||||
._line_number = opts.lineno,
|
||||
._column_number = opts.colno,
|
||||
._error = if (opts.@"error") |err| try err.persist() else null,
|
||||
});
|
||||
|
||||
event._proto._bubbles = opts.bubbles;
|
||||
event._proto._cancelable = opts.cancelable;
|
||||
const event = try page._factory.event(
|
||||
typ,
|
||||
ErrorEvent{
|
||||
._arena = arena,
|
||||
._proto = undefined,
|
||||
._message = if (opts.message) |str| try arena.dupe(u8, str) else "",
|
||||
._filename = if (opts.filename) |str| try arena.dupe(u8, str) else "",
|
||||
._line_number = opts.lineno,
|
||||
._column_number = opts.colno,
|
||||
._error = if (opts.@"error") |err| try err.persist() else null,
|
||||
},
|
||||
);
|
||||
|
||||
Event.populatePrototypes(event, opts);
|
||||
return event;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,27 +29,28 @@ _data: ?js.Object = null,
|
||||
_origin: []const u8 = "",
|
||||
_source: ?*Window = null,
|
||||
|
||||
pub const InitOptions = struct {
|
||||
const MessageEventOptions = struct {
|
||||
data: ?js.Object = null,
|
||||
origin: ?[]const u8 = null,
|
||||
source: ?*Window = null,
|
||||
bubbles: bool = false,
|
||||
cancelable: bool = false,
|
||||
};
|
||||
|
||||
pub fn init(typ: []const u8, opts_: ?InitOptions, page: *Page) !*MessageEvent {
|
||||
const opts = opts_ orelse InitOptions{};
|
||||
const Options = Event.inheritOptions(MessageEvent, MessageEventOptions);
|
||||
|
||||
const event = try page._factory.event(typ, MessageEvent{
|
||||
._proto = undefined,
|
||||
._data = if (opts.data) |d| try d.persist() else null,
|
||||
._origin = if (opts.origin) |str| try page.arena.dupe(u8, str) else "",
|
||||
._source = opts.source,
|
||||
});
|
||||
pub fn init(typ: []const u8, opts_: ?Options, page: *Page) !*MessageEvent {
|
||||
const opts = opts_ orelse Options{};
|
||||
|
||||
event._proto._bubbles = opts.bubbles;
|
||||
event._proto._cancelable = opts.cancelable;
|
||||
const event = try page._factory.event(
|
||||
typ,
|
||||
MessageEvent{
|
||||
._proto = undefined,
|
||||
._data = if (opts.data) |d| try d.persist() else null,
|
||||
._origin = if (opts.origin) |str| try page.arena.dupe(u8, str) else "",
|
||||
._source = opts.source,
|
||||
},
|
||||
);
|
||||
|
||||
Event.populatePrototypes(event, opts);
|
||||
return event;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,26 +30,37 @@ _proto: *Event,
|
||||
_from: *NavigationHistoryEntry,
|
||||
_navigation_type: ?NavigationType,
|
||||
|
||||
pub const EventInit = struct {
|
||||
const NavigationCurrentEntryChangeEventOptions = struct {
|
||||
from: *NavigationHistoryEntry,
|
||||
navigationType: ?[]const u8 = null,
|
||||
};
|
||||
|
||||
const Options = Event.inheritOptions(
|
||||
NavigationCurrentEntryChangeEvent,
|
||||
NavigationCurrentEntryChangeEventOptions,
|
||||
);
|
||||
|
||||
pub fn init(
|
||||
typ: []const u8,
|
||||
init_obj: EventInit,
|
||||
opts: Options,
|
||||
page: *Page,
|
||||
) !*NavigationCurrentEntryChangeEvent {
|
||||
const navigation_type = if (init_obj.navigationType) |nav_type_str|
|
||||
const navigation_type = if (opts.navigationType) |nav_type_str|
|
||||
std.meta.stringToEnum(NavigationType, nav_type_str)
|
||||
else
|
||||
null;
|
||||
|
||||
return page._factory.event(typ, NavigationCurrentEntryChangeEvent{
|
||||
._proto = undefined,
|
||||
._from = init_obj.from,
|
||||
._navigation_type = navigation_type,
|
||||
});
|
||||
const event = try page._factory.event(
|
||||
typ,
|
||||
NavigationCurrentEntryChangeEvent{
|
||||
._proto = undefined,
|
||||
._from = opts.from,
|
||||
._navigation_type = navigation_type,
|
||||
},
|
||||
);
|
||||
|
||||
Event.populatePrototypes(event, opts);
|
||||
return event;
|
||||
}
|
||||
|
||||
pub fn asEvent(self: *NavigationCurrentEntryChangeEvent) *Event {
|
||||
|
||||
@@ -25,18 +25,28 @@ const Page = @import("../../Page.zig");
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/PageTransitionEvent
|
||||
const PageTransitionEvent = @This();
|
||||
|
||||
const EventInit = struct {
|
||||
persisted: ?bool = null,
|
||||
};
|
||||
|
||||
_proto: *Event,
|
||||
_persisted: bool,
|
||||
|
||||
pub fn init(typ: []const u8, init_obj: EventInit, page: *Page) !*PageTransitionEvent {
|
||||
return page._factory.event(typ, PageTransitionEvent{
|
||||
._proto = undefined,
|
||||
._persisted = init_obj.persisted orelse false,
|
||||
});
|
||||
const PageTransitionEventOptions = struct {
|
||||
persisted: ?bool = false,
|
||||
};
|
||||
|
||||
const Options = Event.inheritOptions(PageTransitionEvent, PageTransitionEventOptions);
|
||||
|
||||
pub fn init(typ: []const u8, _opts: ?Options, page: *Page) !*PageTransitionEvent {
|
||||
const opts = _opts orelse Options{};
|
||||
|
||||
const event = try page._factory.event(
|
||||
typ,
|
||||
PageTransitionEvent{
|
||||
._proto = undefined,
|
||||
._persisted = opts.persisted orelse false,
|
||||
},
|
||||
);
|
||||
|
||||
Event.populatePrototypes(event, opts);
|
||||
return event;
|
||||
}
|
||||
|
||||
pub fn asEvent(self: *PageTransitionEvent) *Event {
|
||||
|
||||
@@ -25,20 +25,28 @@ const Page = @import("../../Page.zig");
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/PopStateEvent
|
||||
const PopStateEvent = @This();
|
||||
|
||||
const EventOptions = struct {
|
||||
state: ?[]const u8 = null,
|
||||
};
|
||||
|
||||
_proto: *Event,
|
||||
_state: ?[]const u8,
|
||||
|
||||
pub fn init(typ: []const u8, _options: ?EventOptions, page: *Page) !*PopStateEvent {
|
||||
const options = _options orelse EventOptions{};
|
||||
const PopStateEventOptions = struct {
|
||||
state: ?[]const u8 = null,
|
||||
};
|
||||
|
||||
return page._factory.event(typ, PopStateEvent{
|
||||
._proto = undefined,
|
||||
._state = options.state,
|
||||
});
|
||||
const Options = Event.inheritOptions(PopStateEvent, PopStateEventOptions);
|
||||
|
||||
pub fn init(typ: []const u8, _opts: ?Options, page: *Page) !*PopStateEvent {
|
||||
const opts = _opts orelse Options{};
|
||||
|
||||
const event = try page._factory.event(
|
||||
typ,
|
||||
PopStateEvent{
|
||||
._proto = undefined,
|
||||
._state = opts.state,
|
||||
},
|
||||
);
|
||||
|
||||
Event.populatePrototypes(event, opts);
|
||||
return event;
|
||||
}
|
||||
|
||||
pub fn asEvent(self: *PopStateEvent) *Event {
|
||||
|
||||
@@ -25,12 +25,28 @@ _total: usize = 0,
|
||||
_loaded: usize = 0,
|
||||
_length_computable: bool = false,
|
||||
|
||||
pub fn init(typ: []const u8, total: usize, loaded: usize, page: *Page) !*ProgressEvent {
|
||||
return page._factory.event(typ, ProgressEvent{
|
||||
._proto = undefined,
|
||||
._total = total,
|
||||
._loaded = loaded,
|
||||
});
|
||||
const ProgressEventOptions = struct {
|
||||
total: usize = 0,
|
||||
loaded: usize = 0,
|
||||
lengthComputable: bool = false,
|
||||
};
|
||||
|
||||
const Options = Event.inheritOptions(ProgressEvent, ProgressEventOptions);
|
||||
|
||||
pub fn init(typ: []const u8, _opts: ?Options, page: *Page) !*ProgressEvent {
|
||||
const opts = _opts orelse Options{};
|
||||
|
||||
const event = try page._factory.event(
|
||||
typ,
|
||||
ProgressEvent{
|
||||
._proto = undefined,
|
||||
._total = opts.total,
|
||||
._loaded = opts.loaded,
|
||||
},
|
||||
);
|
||||
|
||||
Event.populatePrototypes(event, opts);
|
||||
return event;
|
||||
}
|
||||
|
||||
pub fn asEvent(self: *ProgressEvent) *Event {
|
||||
|
||||
@@ -57,7 +57,11 @@ pub fn dispatch(self: *XMLHttpRequestEventTarget, comptime event_type: DispatchT
|
||||
};
|
||||
|
||||
const progress = progress_ orelse Progress{};
|
||||
const event = try ProgressEvent.init(typ, progress.total, progress.loaded, page);
|
||||
const event = try ProgressEvent.init(
|
||||
typ,
|
||||
.{ .total = progress.total, .loaded = progress.loaded },
|
||||
page,
|
||||
);
|
||||
|
||||
return page._event_manager.dispatchWithFunction(
|
||||
self.asEventTarget(),
|
||||
|
||||
Reference in New Issue
Block a user