diff --git a/src/browser/Page.zig b/src/browser/Page.zig index 1a8a8c25..28d47af0 100644 --- a/src/browser/Page.zig +++ b/src/browser/Page.zig @@ -723,22 +723,13 @@ pub fn documentIsComplete(self: *Page) void { fn _documentIsComplete(self: *Page) !void { self.document._ready_state = .complete; + // Run load events before window.load. + try self.dispatchLoad(); + var ls: JS.Local.Scope = undefined; self.js.localScope(&ls); defer ls.deinit(); - { - // Dispatch `_to_load` events before window.load. - const has_dom_load_listener = self._event_manager.has_dom_load_listener; - for (self._to_load.items) |html_element| { - if (has_dom_load_listener or html_element.hasAttributeFunction(.onload, self)) { - const event = try Event.initTrusted(comptime .wrap("load"), .{}, self); - try self._event_manager.dispatch(html_element.asEventTarget(), event); - } - } - } - self._to_load.clearRetainingCapacity(); - // Dispatch window.load event. const event = try Event.initTrusted(comptime .wrap("load"), .{}, self); // This event is weird, it's dispatched directly on the window, but @@ -1059,14 +1050,7 @@ pub fn linkAddedCallback(self: *Page, link: *Element.Html.Link) !void { const href = element.getAttributeSafe(comptime .wrap("href")) orelse return; if (href.len == 0) return; - // If `_to_load` len was 0, we have to schedule a callback on scheduler. - const loads = &self._to_load; - const not_scheduled = loads.items.len == 0; - try loads.append(self.arena, link._proto); - - if (not_scheduled) { - try self.scheduleLoadEventDelivery(); - } + try self._to_load.append(self.arena, link._proto); } pub fn domChanged(self: *Page) void { @@ -1241,34 +1225,16 @@ pub fn checkIntersections(self: *Page) !void { } } -pub fn scheduleLoadEventDelivery(self: *Page) !void { - // The dispatcher function. - const callback = struct { - fn callback(ptr: *anyopaque) anyerror!?u32 { - const page: *Page = @ptrCast(@alignCast(ptr)); - const has_dom_load_listener = page._event_manager.has_dom_load_listener; - for (page._to_load.items) |html_element| { - if (has_dom_load_listener or html_element.hasAttributeFunction(.onload, page)) { - const event = try Event.initTrusted(comptime .wrap("load"), .{}, page); - try page._event_manager.dispatch(html_element.asEventTarget(), event); - } - } - // We drained everything. - page._to_load.clearRetainingCapacity(); - - return null; +pub fn dispatchLoad(self: *Page) !void { + const has_dom_load_listener = self._event_manager.has_dom_load_listener; + for (self._to_load.items) |html_element| { + if (has_dom_load_listener or html_element.hasAttributeFunction(.onload, self)) { + const event = try Event.initTrusted(comptime .wrap("load"), .{}, self); + try self._event_manager.dispatch(html_element.asEventTarget(), event); } - }.callback; - - return self.js.scheduler.add( - self, - callback, - 0, - .{ - .low_priority = false, - .name = "scheduleLoadEventDelivery", - }, - ); + } + // We drained everything. + self._to_load.clearRetainingCapacity(); } pub fn scheduleMutationDelivery(self: *Page) !void { diff --git a/src/browser/Session.zig b/src/browser/Session.zig index 18468933..540ba520 100644 --- a/src/browser/Session.zig +++ b/src/browser/Session.zig @@ -241,6 +241,9 @@ fn _wait(self: *Session, page: *Page, wait_ms: u32) !WaitResult { // it AFTER. const ms_to_next_task = try browser.runMacrotasks(); + // Each call to this runs scheduled load events. + try page.dispatchLoad(); + const http_active = http_client.active; const total_network_activity = http_active + http_client.intercepted; if (page._notified_network_almost_idle.check(total_network_activity <= 2)) {