From 4f127c9de3a8490fe80c121690da148b3c21d86c Mon Sep 17 00:00:00 2001 From: Karl Seguin Date: Mon, 15 Sep 2025 22:24:35 +0800 Subject: [PATCH] Bubble events to the Window --- src/browser/dom/event_target.zig | 18 ++++++++++++++++-- src/browser/netsurf.zig | 2 +- src/tests/events/custom.html | 8 ++++++++ 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/browser/dom/event_target.zig b/src/browser/dom/event_target.zig index 3d239629..c214cf48 100644 --- a/src/browser/dom/event_target.zig +++ b/src/browser/dom/event_target.zig @@ -148,8 +148,22 @@ pub const EventTarget = struct { ); } - pub fn _dispatchEvent(self: *parser.EventTarget, event: *parser.Event) !bool { - return try parser.eventTargetDispatchEvent(self, event); + pub fn _dispatchEvent(self: *parser.EventTarget, event: *parser.Event, page: *Page) !bool { + const res = try parser.eventTargetDispatchEvent(self, event); + + // TODO: If we get this working, we should also create a getter to check + // stopPropagation and not bubble to window if true. + if (!parser.eventBubbles(event)) { + return res; + } + + // I think this mutates `event`, which means any JavaScript that captured + // it will be mutated incorrectly. + const Window = @import("../html/window.zig").Window; + return parser.eventTargetDispatchEvent( + parser.toEventTarget(Window, &page.window), + event, + ); } }; diff --git a/src/browser/netsurf.zig b/src/browser/netsurf.zig index 01aeb82c..d33f0790 100644 --- a/src/browser/netsurf.zig +++ b/src/browser/netsurf.zig @@ -604,7 +604,7 @@ fn eventTargetVtable(et: *EventTarget) c.dom_event_target_vtable { return @as([*c]const c.dom_event_target_vtable, @ptrCast(vtable_aligned)).*; } -pub inline fn toEventTarget(comptime T: type, v: *T) *EventTarget { +pub fn toEventTarget(comptime T: type, v: *T) *EventTarget { if (comptime eventTargetTBaseFieldName(T)) |field| { const et_aligned: *align(@alignOf(EventTarget)) EventTargetTBase = @alignCast(&@field(v, field)); return @as(*EventTarget, @ptrCast(et_aligned)); diff --git a/src/tests/events/custom.html b/src/tests/events/custom.html index e749fe05..ed7e0faf 100644 --- a/src/tests/events/custom.html +++ b/src/tests/events/custom.html @@ -13,4 +13,12 @@ el.dispatchEvent(new CustomEvent('c2', {detail: {over: 9000}})); testing.expectEqual("c2-9000", capture); + + let window_calls = 0; + window.addEventListener('c1', () => { + window_calls += 1; + }); + + el.dispatchEvent(new CustomEvent('c1', {bubbles: true})); + testing.expectEqual(1, window_calls);