fix(webkit): do not poll readyState if target is paused before first navigation (#721)

This commit is contained in:
Yury Semikhatsky 2020-01-28 14:00:36 -08:00 committed by Dmitry Gozman
parent 9d34f28a40
commit 460527d8cb
2 changed files with 37 additions and 23 deletions

View file

@ -84,11 +84,11 @@ export class WKPage implements PageDelegate {
this._workers.setSession(session); this._workers.setSession(session);
} }
async initialize(session: WKSession) { async initialize(session: WKSession, pagePausedOnStart: boolean) {
this._setSession(session); this._setSession(session);
await Promise.all([ await Promise.all([
this._initializePageProxySession(), this._initializePageProxySession(),
this._initializeSession(this._session, ({frameTree}) => this._handleFrameTree(frameTree)), this._initializeSession(this._session, ({frameTree}) => this._handleFrameTree(frameTree, pagePausedOnStart)),
]); ]);
} }
@ -234,10 +234,11 @@ export class WKPage implements PageDelegate {
this._page._frameManager.frameLifecycleEvent(frameId, event); this._page._frameManager.frameLifecycleEvent(frameId, event);
} }
private _handleFrameTree(frameTree: Protocol.Page.FrameResourceTree) { private _handleFrameTree(frameTree: Protocol.Page.FrameResourceTree, pagePausedOnStart: boolean) {
const frame = this._onFrameAttached(frameTree.frame.id, frameTree.frame.parentId || null); const frame = this._onFrameAttached(frameTree.frame.id, frameTree.frame.parentId || null);
this._onFrameNavigated(frameTree.frame, true); this._onFrameNavigated(frameTree.frame, true);
if (!pagePausedOnStart) {
frame._utilityContext().then(async context => { frame._utilityContext().then(async context => {
const readyState = await context.evaluate(() => document.readyState).catch(e => 'loading'); const readyState = await context.evaluate(() => document.readyState).catch(e => 'loading');
if (frame.isDetached()) if (frame.isDetached())
@ -247,11 +248,12 @@ export class WKPage implements PageDelegate {
if (readyState === 'complete') if (readyState === 'complete')
this._page._frameManager.frameLifecycleEvent(frame._id, 'load'); this._page._frameManager.frameLifecycleEvent(frame._id, 'load');
}); });
}
if (!frameTree.childFrames) if (!frameTree.childFrames)
return; return;
for (const child of frameTree.childFrames) for (const child of frameTree.childFrames)
this._handleFrameTree(child); this._handleFrameTree(child, pagePausedOnStart);
} }
_onFrameAttached(frameId: string, parentFrameId: string | null): frames.Frame { _onFrameAttached(frameId: string, parentFrameId: string | null): frames.Frame {

View file

@ -32,6 +32,7 @@ export class WKPageProxy {
private _wkPage: WKPage | null = null; private _wkPage: WKPage | null = null;
private readonly _firstTargetPromise: Promise<void>; private readonly _firstTargetPromise: Promise<void>;
private _firstTargetCallback?: () => void; private _firstTargetCallback?: () => void;
private _pagePausedOnStart: boolean = false;
private readonly _sessions = new Map<string, WKSession>(); private readonly _sessions = new Map<string, WKSession>();
private readonly _eventListeners: RegisteredListener[]; private readonly _eventListeners: RegisteredListener[];
@ -121,7 +122,11 @@ export class WKPageProxy {
} }
assert(session, 'One non-provisional target session must exist'); assert(session, 'One non-provisional target session must exist');
this._wkPage = new WKPage(this._browserContext, this._pageProxySession); this._wkPage = new WKPage(this._browserContext, this._pageProxySession);
await this._wkPage.initialize(session!); await this._wkPage.initialize(session!, this._pagePausedOnStart);
if (this._pagePausedOnStart) {
this._resumeTarget(session!.sessionId);
this._pagePausedOnStart = false;
}
return this._wkPage._page; return this._wkPage._page;
} }
@ -140,19 +145,26 @@ export class WKPageProxy {
this._firstTargetCallback(); this._firstTargetCallback();
this._firstTargetCallback = undefined; this._firstTargetCallback = undefined;
} }
if (targetInfo.isProvisional) if (targetInfo.isProvisional) {
(session as any)[isPovisionalSymbol] = true; (session as any)[isPovisionalSymbol] = true;
if (targetInfo.isProvisional && this._wkPage) if (this._wkPage)
this._wkPage.onProvisionalLoadStarted(session); this._wkPage.onProvisionalLoadStarted(session);
if (targetInfo.isPaused) { if (targetInfo.isPaused)
const resume = () => this._pageProxySession.send('Target.resume', { targetId: targetInfo.targetId }).catch(debugError); this._resumeTarget(targetInfo.targetId);
if (targetInfo.isProvisional || !this._pagePromise) } else if (this._pagePromise) {
resume(); assert(!this._pagePausedOnStart);
else // This is the first time page target is created, will resume
this._pagePromise.then(resume); // after finishing intialization.
this._pagePausedOnStart = !!targetInfo.isPaused;
} else if (targetInfo.isPaused) {
this._resumeTarget(targetInfo.targetId);
} }
} }
private _resumeTarget(targetId: string) {
this._pageProxySession.send('Target.resume', { targetId }).catch(debugError);
}
private _onTargetDestroyed(event: Protocol.Target.targetDestroyedPayload) { private _onTargetDestroyed(event: Protocol.Target.targetDestroyedPayload) {
const { targetId, crashed } = event; const { targetId, crashed } = event;
const session = this._sessions.get(targetId); const session = this._sessions.get(targetId);