mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-10-29 15:13:28 +00:00
Fix crash when event target is the window.
On page load, emitted by the page, the target is the window, but it's improperly cast since the pointer is actually `window.base`. This is going to be a problem in general for any Zig type dispatched as a target, but the Window one is the most obvious and the easiest to fix. If this issue comes up with other types, we'll need to come up with a more robust solution.
This commit is contained in:
@@ -33,9 +33,15 @@ pub const EventTarget = struct {
|
|||||||
pub const Self = parser.EventTarget;
|
pub const Self = parser.EventTarget;
|
||||||
pub const Exception = DOMException;
|
pub const Exception = DOMException;
|
||||||
|
|
||||||
pub fn toInterface(et: *parser.EventTarget) !Union {
|
pub fn toInterface(et: *parser.EventTarget, page: *Page) !Union {
|
||||||
// NOTE: for now we state that all EventTarget are Nodes
|
// Not all targets are *parser.Nodes. page.zig emits a "load" event
|
||||||
// TODO: handle other types (eg. Window)
|
// where the target is a Window, which cannot be cast directly to a node.
|
||||||
|
// Ideally, we'd remove this duality. Failing that, we'll need to embed
|
||||||
|
// data into the *parser.EventTarget should we need this for other types.
|
||||||
|
// For now, for the Window, which is a singleton, we can do this:
|
||||||
|
if (@intFromPtr(et) == @intFromPtr(&page.window.base)) {
|
||||||
|
return .{ .Window = &page.window };
|
||||||
|
}
|
||||||
return Nod.Node.toInterface(@as(*parser.Node, @ptrCast(et)));
|
return Nod.Node.toInterface(@as(*parser.Node, @ptrCast(et)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ const JsObject = @import("../env.zig").JsObject;
|
|||||||
// https://dom.spec.whatwg.org/#interface-customevent
|
// https://dom.spec.whatwg.org/#interface-customevent
|
||||||
pub const CustomEvent = struct {
|
pub const CustomEvent = struct {
|
||||||
pub const prototype = *Event;
|
pub const prototype = *Event;
|
||||||
|
pub const union_make_copy = true;
|
||||||
|
|
||||||
proto: parser.Event,
|
proto: parser.Event,
|
||||||
detail: ?JsObject,
|
detail: ?JsObject,
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ const log = @import("../../log.zig");
|
|||||||
const parser = @import("../netsurf.zig");
|
const parser = @import("../netsurf.zig");
|
||||||
const generate = @import("../../runtime/generate.zig");
|
const generate = @import("../../runtime/generate.zig");
|
||||||
|
|
||||||
|
const Page = @import("../page.zig").Page;
|
||||||
const DOMException = @import("../dom/exceptions.zig").DOMException;
|
const DOMException = @import("../dom/exceptions.zig").DOMException;
|
||||||
const EventTarget = @import("../dom/event_target.zig").EventTarget;
|
const EventTarget = @import("../dom/event_target.zig").EventTarget;
|
||||||
const EventTargetUnion = @import("../dom/event_target.zig").Union;
|
const EventTargetUnion = @import("../dom/event_target.zig").Union;
|
||||||
@@ -76,16 +77,16 @@ pub const Event = struct {
|
|||||||
return try parser.eventType(self);
|
return try parser.eventType(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_target(self: *parser.Event) !?EventTargetUnion {
|
pub fn get_target(self: *parser.Event, page: *Page) !?EventTargetUnion {
|
||||||
const et = try parser.eventTarget(self);
|
const et = try parser.eventTarget(self);
|
||||||
if (et == null) return null;
|
if (et == null) return null;
|
||||||
return try EventTarget.toInterface(et.?);
|
return try EventTarget.toInterface(et.?, page);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_currentTarget(self: *parser.Event) !?EventTargetUnion {
|
pub fn get_currentTarget(self: *parser.Event, page: *Page) !?EventTargetUnion {
|
||||||
const et = try parser.eventCurrentTarget(self);
|
const et = try parser.eventCurrentTarget(self);
|
||||||
if (et == null) return null;
|
if (et == null) return null;
|
||||||
return try EventTarget.toInterface(et.?);
|
return try EventTarget.toInterface(et.?, page);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_eventPhase(self: *parser.Event) !u8 {
|
pub fn get_eventPhase(self: *parser.Event) !u8 {
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ const DOMException = @import("../dom/exceptions.zig").DOMException;
|
|||||||
pub const ProgressEvent = struct {
|
pub const ProgressEvent = struct {
|
||||||
pub const prototype = *Event;
|
pub const prototype = *Event;
|
||||||
pub const Exception = DOMException;
|
pub const Exception = DOMException;
|
||||||
|
pub const union_make_copy = true;
|
||||||
|
|
||||||
pub const EventInit = struct {
|
pub const EventInit = struct {
|
||||||
lengthComputable: bool = false,
|
lengthComputable: bool = false,
|
||||||
|
|||||||
@@ -71,6 +71,8 @@ pub fn Union(comptime interfaces: anytype) type {
|
|||||||
var FT = @field(tuple, field.name);
|
var FT = @field(tuple, field.name);
|
||||||
if (@hasDecl(FT, "Self")) {
|
if (@hasDecl(FT, "Self")) {
|
||||||
FT = *(@field(FT, "Self"));
|
FT = *(@field(FT, "Self"));
|
||||||
|
} else if (!@hasDecl(FT, "union_make_copy")) {
|
||||||
|
FT = *FT;
|
||||||
}
|
}
|
||||||
union_fields[index] = .{
|
union_fields[index] = .{
|
||||||
.type = FT,
|
.type = FT,
|
||||||
@@ -171,7 +173,7 @@ fn filterMap(comptime count: usize, interfaces: [count]type) struct { usize, [co
|
|||||||
return .{ unfiltered_count, map };
|
return .{ unfiltered_count, map };
|
||||||
}
|
}
|
||||||
|
|
||||||
test "generate.Union" {
|
test "generate: Union" {
|
||||||
const Astruct = struct {
|
const Astruct = struct {
|
||||||
pub const Self = Other;
|
pub const Self = Other;
|
||||||
const Other = struct {};
|
const Other = struct {};
|
||||||
@@ -188,15 +190,15 @@ test "generate.Union" {
|
|||||||
const value = Union(.{ Astruct, Bstruct, .{Cstruct} });
|
const value = Union(.{ Astruct, Bstruct, .{Cstruct} });
|
||||||
const ti = @typeInfo(value).@"union";
|
const ti = @typeInfo(value).@"union";
|
||||||
try std.testing.expectEqual(3, ti.fields.len);
|
try std.testing.expectEqual(3, ti.fields.len);
|
||||||
try std.testing.expectEqualStrings("*runtime.generate.test.generate.Union.Astruct.Other", @typeName(ti.fields[0].type));
|
try std.testing.expectEqualStrings("*runtime.generate.test.generate: Union.Astruct.Other", @typeName(ti.fields[0].type));
|
||||||
try std.testing.expectEqualStrings(ti.fields[0].name, "Astruct");
|
try std.testing.expectEqualStrings(ti.fields[0].name, "Astruct");
|
||||||
try std.testing.expectEqual(Bstruct, ti.fields[1].type);
|
try std.testing.expectEqual(*Bstruct, ti.fields[1].type);
|
||||||
try std.testing.expectEqualStrings(ti.fields[1].name, "Bstruct");
|
try std.testing.expectEqualStrings(ti.fields[1].name, "Bstruct");
|
||||||
try std.testing.expectEqual(Cstruct, ti.fields[2].type);
|
try std.testing.expectEqual(*Cstruct, ti.fields[2].type);
|
||||||
try std.testing.expectEqualStrings(ti.fields[2].name, "Cstruct");
|
try std.testing.expectEqualStrings(ti.fields[2].name, "Cstruct");
|
||||||
}
|
}
|
||||||
|
|
||||||
test "generate.Tuple" {
|
test "generate: Tuple" {
|
||||||
const Astruct = struct {};
|
const Astruct = struct {};
|
||||||
|
|
||||||
const Bstruct = struct {
|
const Bstruct = struct {
|
||||||
|
|||||||
Reference in New Issue
Block a user