Skip to content

Commit 5cf4ba2

Browse files
authored
fix: dispatch FrameDetached before detaching frame in FrameManager (#3454)
Mirrors upstream Puppeteer PR #14430 ("perf: dispose sub-classes correctly"). In the original change, frame disposal was moved to run after the FrameDetached events fire so that listeners aren't torn down before they can observe the event. Most of upstream's changes target TypeScript's disposeSymbol / asyncDisposeSymbol pattern and an internal EventEmitter that removes all listeners on dispose. PuppeteerSharp uses standard C# events, which keep their delegate list intact across Dispose, so the underlying bug does not manifest the same way. The one place the structural ordering matters is FrameManager.RemoveFramesRecursively, where Frame.Detach performs internal cleanup (world detachment, etc.) before emitting FrameDetached on the frame itself. Reordering aligns us with upstream and keeps event observability consistent with the rest of the codebase. Refs: puppeteer/puppeteer#14430
1 parent 4f8ead1 commit 5cf4ba2

1 file changed

Lines changed: 4 additions & 1 deletion

File tree

lib/PuppeteerSharp/Cdp/FrameManager.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -576,9 +576,12 @@ private void RemoveFramesRecursively(Frame frame)
576576
RemoveFramesRecursively(frame.ChildFrames.First() as Frame);
577577
}
578578

579-
frame.Detach();
580579
FrameTree.RemoveFrame(frame);
581580
FrameDetached?.Invoke(this, new FrameEventArgs(frame));
581+
582+
// Needs to be last to ensure events are dispatched before
583+
// any per-frame cleanup runs. Mirrors upstream PR #14430.
584+
frame.Detach();
582585
}
583586

584587
private void OnFrameAttached(CDPSession session, PageFrameAttachedResponse frameAttached)

0 commit comments

Comments
 (0)