diff --git a/src/browser/html/window.zig b/src/browser/html/window.zig index 74fa28b3d..f18b0cd2c 100644 --- a/src/browser/html/window.zig +++ b/src/browser/html/window.zig @@ -387,4 +387,19 @@ test "Browser.HTML.Window" { .{ "window.setTimeout(() => {longCall = true}, 5001);", null }, .{ "longCall;", "false" }, }, .{}); + + // window event target + try runner.testCases(&.{ + .{ + \\ let called = false; + \\ window.addEventListener("ready", (e) => { + \\ called = (e.currentTarget == window); + \\ }, {capture: false, once: false}); + \\ const evt = new Event("ready", { bubbles: true, cancelable: false }); + \\ window.dispatchEvent(evt); + \\ called; + , + "true", + }, + }, .{}); } diff --git a/src/browser/netsurf.zig b/src/browser/netsurf.zig index 03db92e24..414dd56d6 100644 --- a/src/browser/netsurf.zig +++ b/src/browser/netsurf.zig @@ -775,6 +775,17 @@ pub const EventTargetTBase = extern struct { .add_event_listener = add_event_listener, .iter_event_listener = iter_event_listener, }, + + // When we dispatch the event, we need to provide a target. In reality, the + // target is the container of this EventTargetTBase. But we can't pass that + // to _dom_event_target_dispatch, because it expects a dom_event_target. + // If you try to pass an non-event_target, you'll get weird behavior. For + // example, libdom might dom_node_ref that memory. Say we passed a *Window + // as the target, what happens if libdom calls dom_node_ref(window)? If + // you're lucky, you'll crash. If you're unlucky, you'll increment a random + // part of the window structure. + refcnt: u32 = 0, + eti: c.dom_event_target_internal = c.dom_event_target_internal{ .listeners = null }, pub fn add_event_listener(et: [*c]c.dom_event_target, t: [*c]c.dom_string, l: ?*c.struct_dom_event_listener, capture: bool) callconv(.C) c.dom_exception {