diff --git a/src/browser/Page.zig b/src/browser/Page.zig index d6ca6347..11da60aa 100644 --- a/src/browser/Page.zig +++ b/src/browser/Page.zig @@ -49,7 +49,6 @@ const Document = @import("webapi/Document.zig"); const ShadowRoot = @import("webapi/ShadowRoot.zig"); const Performance = @import("webapi/Performance.zig"); const Screen = @import("webapi/Screen.zig"); -const HtmlScript = @import("webapi/Element.zig").Html.Script; const PerformanceObserver = @import("webapi/PerformanceObserver.zig"); const MutationObserver = @import("webapi/MutationObserver.zig"); const IntersectionObserver = @import("webapi/IntersectionObserver.zig"); @@ -1067,28 +1066,32 @@ pub fn notifyPerformanceObservers(self: *Page, entry: *Performance.Entry) !void } } - if (self._performance_delivery_scheduled == false) { - self._performance_delivery_scheduled = true; - try self.scheduler.add( - self, - struct { - fn run(_page: *anyopaque) anyerror!?u32 { - const page: *Page = @ptrCast(@alignCast(_page)); - page._performance_delivery_scheduled = true; - // Dispatch performance observer events. - for (page._performance_observers.items) |observer| { - if (observer.hasRecords()) { - try observer.dispatch(page); - } - } - - return null; - } - }.run, - 0, - .{ .low_priority = true }, - ); + // Already scheduled. + if (self._performance_delivery_scheduled) { + return; } + self._performance_delivery_scheduled = true; + + return self.scheduler.add( + self, + struct { + fn run(_page: *anyopaque) anyerror!?u32 { + const page: *Page = @ptrCast(@alignCast(_page)); + page._performance_delivery_scheduled = false; + + // Dispatch performance observer events. + for (page._performance_observers.items) |observer| { + if (observer.hasRecords()) { + try observer.dispatch(page); + } + } + + return null; + } + }.run, + 0, + .{ .low_priority = true }, + ); } pub fn registerMutationObserver(self: *Page, observer: *MutationObserver) !void { diff --git a/src/browser/webapi/PerformanceObserver.zig b/src/browser/webapi/PerformanceObserver.zig index be920c1a..7e4d9c5d 100644 --- a/src/browser/webapi/PerformanceObserver.zig +++ b/src/browser/webapi/PerformanceObserver.zig @@ -22,6 +22,10 @@ const js = @import("../js/js.zig"); const Page = @import("../Page.zig"); const Performance = @import("Performance.zig"); +pub fn registerTypes() []const type { + return &.{ PerformanceObserver, EntryList }; +} + /// https://developer.mozilla.org/en-US/docs/Web/API/PerformanceObserver const PerformanceObserver = @This(); @@ -109,8 +113,12 @@ pub fn observe( self._interests = interests; } -pub fn disconnect(self: *PerformanceObserver) void { - _ = self; +pub fn disconnect(self: *PerformanceObserver, page: *Page) void { + page.unregisterPerformanceObserver(self); + // Reset observer. + self._duration_threshold = DefaultDurationThreshold; + self._interests = 0; + self._entries.clearRetainingCapacity(); } /// Returns the current list of PerformanceEntry objects @@ -141,7 +149,7 @@ pub inline fn hasRecords(self: *const PerformanceObserver) bool { /// Runs the PerformanceObserver's callback with records; emptying it out. pub fn dispatch(self: *PerformanceObserver, page: *Page) !void { const records = try self.takeRecords(page); - _ = try self._callback.call(void, .{records}); + _ = try self._callback.call(void, .{ EntryList{ ._entries = records }, self }); } pub const JsApi = struct { @@ -175,11 +183,16 @@ pub const EntryList = struct { pub const bridge = js.Bridge(EntryList); pub const Meta = struct { - pub const name = "PerformanceEntryList"; + pub const name = "PerformanceObserverEntryList"; pub const prototype_chain = bridge.prototypeChain(); pub var class_id: bridge.ClassId = undefined; - - pub const getEntries = bridge.function(EntryList.getEntries, .{}); }; + + pub const getEntries = bridge.function(EntryList.getEntries, .{}); }; }; + +const testing = @import("../../testing.zig"); +test "WebApi: PerformanceObserver" { + try testing.htmlRunner("performance_observer", .{}); +}