Skip to content

Commit fff0a8a

Browse files
authored
Merge pull request #757 from lightpanda-io/window_target_crash
Fix crash when event target is the window.
2 parents 4ff978f + 8904afa commit fff0a8a

File tree

5 files changed

+23
-12
lines changed

5 files changed

+23
-12
lines changed

src/browser/dom/event_target.zig

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,15 @@ pub const EventTarget = struct {
3333
pub const Self = parser.EventTarget;
3434
pub const Exception = DOMException;
3535

36-
pub fn toInterface(et: *parser.EventTarget) !Union {
37-
// NOTE: for now we state that all EventTarget are Nodes
38-
// TODO: handle other types (eg. Window)
36+
pub fn toInterface(et: *parser.EventTarget, page: *Page) !Union {
37+
// Not all targets are *parser.Nodes. page.zig emits a "load" event
38+
// where the target is a Window, which cannot be cast directly to a node.
39+
// Ideally, we'd remove this duality. Failing that, we'll need to embed
40+
// data into the *parser.EventTarget should we need this for other types.
41+
// For now, for the Window, which is a singleton, we can do this:
42+
if (@intFromPtr(et) == @intFromPtr(&page.window.base)) {
43+
return .{ .Window = &page.window };
44+
}
3945
return Nod.Node.toInterface(@as(*parser.Node, @ptrCast(et)));
4046
}
4147

src/browser/events/custom_event.zig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ const JsObject = @import("../env.zig").JsObject;
2323
// https://dom.spec.whatwg.org/#interface-customevent
2424
pub const CustomEvent = struct {
2525
pub const prototype = *Event;
26+
pub const union_make_copy = true;
2627

2728
proto: parser.Event,
2829
detail: ?JsObject,

src/browser/events/event.zig

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ const log = @import("../../log.zig");
2323
const parser = @import("../netsurf.zig");
2424
const generate = @import("../../runtime/generate.zig");
2525

26+
const Page = @import("../page.zig").Page;
2627
const DOMException = @import("../dom/exceptions.zig").DOMException;
2728
const EventTarget = @import("../dom/event_target.zig").EventTarget;
2829
const EventTargetUnion = @import("../dom/event_target.zig").Union;
@@ -76,16 +77,16 @@ pub const Event = struct {
7677
return try parser.eventType(self);
7778
}
7879

79-
pub fn get_target(self: *parser.Event) !?EventTargetUnion {
80+
pub fn get_target(self: *parser.Event, page: *Page) !?EventTargetUnion {
8081
const et = try parser.eventTarget(self);
8182
if (et == null) return null;
82-
return try EventTarget.toInterface(et.?);
83+
return try EventTarget.toInterface(et.?, page);
8384
}
8485

85-
pub fn get_currentTarget(self: *parser.Event) !?EventTargetUnion {
86+
pub fn get_currentTarget(self: *parser.Event, page: *Page) !?EventTargetUnion {
8687
const et = try parser.eventCurrentTarget(self);
8788
if (et == null) return null;
88-
return try EventTarget.toInterface(et.?);
89+
return try EventTarget.toInterface(et.?, page);
8990
}
9091

9192
pub fn get_eventPhase(self: *parser.Event) !u8 {

src/browser/xhr/progress_event.zig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ const DOMException = @import("../dom/exceptions.zig").DOMException;
2424
pub const ProgressEvent = struct {
2525
pub const prototype = *Event;
2626
pub const Exception = DOMException;
27+
pub const union_make_copy = true;
2728

2829
pub const EventInit = struct {
2930
lengthComputable: bool = false,

src/runtime/generate.zig

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ pub fn Union(comptime interfaces: anytype) type {
7171
var FT = @field(tuple, field.name);
7272
if (@hasDecl(FT, "Self")) {
7373
FT = *(@field(FT, "Self"));
74+
} else if (!@hasDecl(FT, "union_make_copy")) {
75+
FT = *FT;
7476
}
7577
union_fields[index] = .{
7678
.type = FT,
@@ -171,7 +173,7 @@ fn filterMap(comptime count: usize, interfaces: [count]type) struct { usize, [co
171173
return .{ unfiltered_count, map };
172174
}
173175

174-
test "generate.Union" {
176+
test "generate: Union" {
175177
const Astruct = struct {
176178
pub const Self = Other;
177179
const Other = struct {};
@@ -188,15 +190,15 @@ test "generate.Union" {
188190
const value = Union(.{ Astruct, Bstruct, .{Cstruct} });
189191
const ti = @typeInfo(value).@"union";
190192
try std.testing.expectEqual(3, ti.fields.len);
191-
try std.testing.expectEqualStrings("*runtime.generate.test.generate.Union.Astruct.Other", @typeName(ti.fields[0].type));
193+
try std.testing.expectEqualStrings("*runtime.generate.test.generate: Union.Astruct.Other", @typeName(ti.fields[0].type));
192194
try std.testing.expectEqualStrings(ti.fields[0].name, "Astruct");
193-
try std.testing.expectEqual(Bstruct, ti.fields[1].type);
195+
try std.testing.expectEqual(*Bstruct, ti.fields[1].type);
194196
try std.testing.expectEqualStrings(ti.fields[1].name, "Bstruct");
195-
try std.testing.expectEqual(Cstruct, ti.fields[2].type);
197+
try std.testing.expectEqual(*Cstruct, ti.fields[2].type);
196198
try std.testing.expectEqualStrings(ti.fields[2].name, "Cstruct");
197199
}
198200

199-
test "generate.Tuple" {
201+
test "generate: Tuple" {
200202
const Astruct = struct {};
201203

202204
const Bstruct = struct {

0 commit comments

Comments
 (0)