refactor: move execution context events (#12402)

This commit is contained in:
Alex Rudenko 2024-05-07 09:50:56 +02:00 committed by GitHub
parent dfa999da0f
commit 0eae3d1bb6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 27 additions and 45 deletions

View File

@ -6,7 +6,7 @@
import type {Protocol} from 'devtools-protocol';
import type {CDPSession, CDPSessionEvents} from '../api/CDPSession.js';
import type {CDPSession} from '../api/CDPSession.js';
import type {ElementHandle} from '../api/ElementHandle.js';
import type {JSHandle} from '../api/JSHandle.js';
import {EventEmitter} from '../common/EventEmitter.js';
@ -62,31 +62,42 @@ const ariaQuerySelectorAllBinding = new Binding(
/**
* @internal
*/
export class ExecutionContext implements Disposable {
export class ExecutionContext
extends EventEmitter<{
/** Emitted when this execution context is disposed. */
disposed: undefined;
}>
implements Disposable
{
_client: CDPSession;
_world: IsolatedWorld;
_contextId: number;
_contextName?: string;
readonly #disposables = new DisposableStack();
readonly #clientEmitter: EventEmitter<CDPSessionEvents>;
constructor(
client: CDPSession,
contextPayload: Protocol.Runtime.ExecutionContextDescription,
world: IsolatedWorld
) {
super();
this._client = client;
this._world = world;
this._contextId = contextPayload.id;
if (contextPayload.name) {
this._contextName = contextPayload.name;
}
this.#clientEmitter = this.#disposables.use(new EventEmitter(this._client));
this.#clientEmitter.on(
'Runtime.bindingCalled',
this.#onBindingCalled.bind(this)
);
const clientEmitter = this.#disposables.use(new EventEmitter(this._client));
clientEmitter.on('Runtime.bindingCalled', this.#onBindingCalled.bind(this));
clientEmitter.on('Runtime.executionContextDestroyed', async event => {
if (event.executionContextId === this._contextId) {
this[disposeSymbol]();
}
});
clientEmitter.on('Runtime.executionContextsCleared', async () => {
this[disposeSymbol]();
});
}
// Contains mapping from functions that should be bound to Puppeteer functions.
@ -456,6 +467,7 @@ export class ExecutionContext implements Disposable {
[disposeSymbol](): void {
this.#disposables.dispose();
this.emit('disposed', undefined);
}
}

View File

@ -122,8 +122,6 @@ export class FrameManager extends EventEmitter<FrameManagerEvents> {
* its frame tree and ID.
*/
async swapFrameTree(client: CDPSession): Promise<void> {
this.#onExecutionContextsCleared(this.#client);
this.#client = client;
assert(
this.#client instanceof CdpCDPSession,
@ -188,14 +186,6 @@ export class FrameManager extends EventEmitter<FrameManagerEvents> {
await this.#frameTreeHandled?.valueOrThrow();
this.#onExecutionContextCreated(event.context, session);
});
session.on('Runtime.executionContextDestroyed', async event => {
await this.#frameTreeHandled?.valueOrThrow();
this.#onExecutionContextDestroyed(event.executionContextId, session);
});
session.on('Runtime.executionContextsCleared', async () => {
await this.#frameTreeHandled?.valueOrThrow();
this.#onExecutionContextsCleared(session);
});
session.on('Page.lifecycleEvent', async event => {
await this.#frameTreeHandled?.valueOrThrow();
this.#onLifecycleEvent(event);
@ -505,35 +495,15 @@ export class FrameManager extends EventEmitter<FrameManagerEvents> {
}
const key = `${session.id()}:${contextPayload.id}`;
this.#contextIdToContext.set(key, context);
}
#onExecutionContextDestroyed(
executionContextId: number,
session: CDPSession
): void {
const key = `${session.id()}:${executionContextId}`;
context.once('disposed', () => {
const key = `${session.id()}:${contextPayload.id}`;
const context = this.#contextIdToContext.get(key);
if (!context) {
return;
}
this.#contextIdToContext.delete(key);
if (context._world) {
context._world.clearContext();
}
}
#onExecutionContextsCleared(session: CDPSession): void {
for (const [key, context] of this.#contextIdToContext.entries()) {
// Make sure to only clear execution contexts that belong
// to the current session.
if (context._client !== session) {
continue;
}
if (context._world) {
context._world.clearContext();
}
this.#contextIdToContext.delete(key);
}
});
}
#removeFramesRecursively(frame: CdpFrame): void {