explicitly request main frame id from the provisional page

This commit is contained in:
Yury Semikhatsky 2020-01-17 15:21:29 -08:00
parent 57c12ae55c
commit d8ab36c9f7
3 changed files with 39 additions and 28 deletions

View file

@ -60,7 +60,7 @@ export class WKPage implements PageDelegate {
this._session = undefined as any as WKSession; this._session = undefined as any as WKSession;
} }
async _initializePageProxySession() { private async _initializePageProxySession() {
const promises : Promise<any>[] = [ const promises : Promise<any>[] = [
this._pageProxySession.send('Dialog.enable'), this._pageProxySession.send('Dialog.enable'),
this._networkManager.initializePageProxySession(this._page._state.credentials) this._networkManager.initializePageProxySession(this._page._state.credentials)
@ -87,17 +87,21 @@ export class WKPage implements PageDelegate {
this._setBootstrapScripts(session).catch(e => debugError(e)); this._setBootstrapScripts(session).catch(e => debugError(e));
} }
async initialize() {
await Promise.all([
this._initializePageProxySession(),
this._initializeSession(this._session, ({frameTree}) => this._handleFrameTree(frameTree)),
]);
}
// This method is called for provisional targets as well. The session passed as the parameter // This method is called for provisional targets as well. The session passed as the parameter
// may be different from the current session and may be destroyed without becoming current. // may be different from the current session and may be destroyed without becoming current.
async _initializeSession(session: WKSession) { async _initializeSession(session: WKSession, resourceTreeHandler: (r: Protocol.Page.getResourceTreeReturnValue) => void) {
const isProvisional = this._session !== session; const isProvisional = this._session !== session;
const promises : Promise<any>[] = [ const promises : Promise<any>[] = [
// Page agent must be enabled before Runtime. // Page agent must be enabled before Runtime.
session.send('Page.enable') session.send('Page.enable'),
]; session.send('Page.getResourceTree').then(resourceTreeHandler),
if (!isProvisional)
promises.push(session.send('Page.getResourceTree').then(({frameTree}) => this._handleFrameTree(frameTree)));
promises.push(
// Resource tree should be received before first execution context. // Resource tree should be received before first execution context.
session.send('Runtime.enable'), session.send('Runtime.enable'),
session.send('Page.createIsolatedWorld', { name: UTILITY_WORLD_NAME, source: `//# sourceURL=${EVALUATION_SCRIPT_URL}` }), session.send('Page.createIsolatedWorld', { name: UTILITY_WORLD_NAME, source: `//# sourceURL=${EVALUATION_SCRIPT_URL}` }),
@ -105,7 +109,7 @@ export class WKPage implements PageDelegate {
session.send('Page.setInterceptFileChooserDialog', { enabled: true }), session.send('Page.setInterceptFileChooserDialog', { enabled: true }),
this._networkManager.initializeSession(session, this._page._state.interceptNetwork, this._page._state.offlineMode), this._networkManager.initializeSession(session, this._page._state.interceptNetwork, this._page._state.offlineMode),
this._workers.initializeSession(session) this._workers.initializeSession(session)
); ];
const contextOptions = this._page.browserContext()._options; const contextOptions = this._page.browserContext()._options;
if (contextOptions.userAgent) if (contextOptions.userAgent)
promises.push(session.send('Page.overrideUserAgent', { value: contextOptions.userAgent })); promises.push(session.send('Page.overrideUserAgent', { value: contextOptions.userAgent }));
@ -190,10 +194,7 @@ export class WKPage implements PageDelegate {
} }
_onFrameNavigated(framePayload: Protocol.Page.Frame, initial: boolean) { _onFrameNavigated(framePayload: Protocol.Page.Frame, initial: boolean) {
let frame = this._page._frameManager.frame(framePayload.id); const frame = this._page._frameManager.frame(framePayload.id);
const newProcessMainFrame = !frame && !framePayload.parentId;
if (newProcessMainFrame)
frame = this._page._frameManager.mainFrame();
for (const [contextId, context] of this._contextIdToContext) { for (const [contextId, context] of this._contextIdToContext) {
if (context.frame === frame) { if (context.frame === frame) {
(context._delegate as WKExecutionContext)._dispose(); (context._delegate as WKExecutionContext)._dispose();
@ -201,8 +202,6 @@ export class WKPage implements PageDelegate {
frame._contextDestroyed(context); frame._contextDestroyed(context);
} }
} }
if (newProcessMainFrame)
this._onFrameAttached(framePayload.id, null);
this._page._frameManager.frameCommittedNewDocumentNavigation(framePayload.id, framePayload.url, framePayload.name || '', framePayload.loaderId, initial); this._page._frameManager.frameCommittedNewDocumentNavigation(framePayload.id, framePayload.url, framePayload.name || '', framePayload.loaderId, initial);
} }

View file

@ -124,10 +124,7 @@ 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);
this._wkPage.setSession(session!); this._wkPage.setSession(session!);
await Promise.all([ await this._wkPage.initialize();
this._wkPage._initializePageProxySession(),
this._wkPage._initializeSession(session!),
]);
return this._wkPage._page; return this._wkPage._page;
} }
@ -151,7 +148,6 @@ export class WKPageProxy {
if (targetInfo.isProvisional && this._wkPage) { if (targetInfo.isProvisional && this._wkPage) {
assert(!this._provisionalPage); assert(!this._provisionalPage);
this._provisionalPage = new WKProvisionalPage(session, this._wkPage); this._provisionalPage = new WKProvisionalPage(session, this._wkPage);
this._wkPage._initializeSession(session);
} }
if (targetInfo.isPaused) if (targetInfo.isPaused)
this._pageProxySession.send('Target.resume', { targetId: targetInfo.targetId }).catch(debugError); this._pageProxySession.send('Target.resume', { targetId: targetInfo.targetId }).catch(debugError);
@ -188,6 +184,7 @@ export class WKPageProxy {
oldSession!.errorText = 'Target was swapped out.'; oldSession!.errorText = 'Target was swapped out.';
(newSession as any)[isPovisionalSymbol] = undefined; (newSession as any)[isPovisionalSymbol] = undefined;
if (this._provisionalPage) { if (this._provisionalPage) {
this._provisionalPage.commit();
this._provisionalPage.dispose(); this._provisionalPage.dispose();
this._provisionalPage = null; this._provisionalPage = null;
} }

View file

@ -16,12 +16,14 @@
import { WKSession } from './wkConnection'; import { WKSession } from './wkConnection';
import { WKPage } from './wkPage'; import { WKPage } from './wkPage';
import { RegisteredListener, helper } from '../helper'; import { RegisteredListener, helper, assert } from '../helper';
import { Protocol } from './protocol';
export class WKProvisionalPage { export class WKProvisionalPage {
readonly _session: WKSession; readonly _session: WKSession;
private readonly _wkPage: WKPage; private readonly _wkPage: WKPage;
private _sessionListeners: RegisteredListener[] = []; private _sessionListeners: RegisteredListener[] = [];
private _mainFrameId: string | null = null;
constructor(session: WKSession, page: WKPage) { constructor(session: WKSession, page: WKPage) {
this._session = session; this._session = session;
@ -34,7 +36,19 @@ export class WKProvisionalPage {
'Network.loadingFinished', 'Network.loadingFinished',
'Network.loadingFailed', 'Network.loadingFailed',
].map(name => helper.addEventListener(this._session, name, args => this._onNetworkEvent(name, args))); ].map(name => helper.addEventListener(this._session, name, args => this._onNetworkEvent(name, args)));
this._wkPage._initializeSession(session, ({frameTree}) => this._handleFrameTree(frameTree));
} }
dispose() {
helper.removeEventListeners(this._sessionListeners);
}
commit() {
assert(this._mainFrameId);
this._wkPage._onFrameAttached(this._mainFrameId!, null);
}
private _onNetworkEvent(eventName: string, payload: any) { private _onNetworkEvent(eventName: string, payload: any) {
// Pretend that the events happened in the same process. // Pretend that the events happened in the same process.
if (payload.frameId) if (payload.frameId)
@ -42,7 +56,8 @@ export class WKProvisionalPage {
this._wkPage._session.emit(eventName, payload); this._wkPage._session.emit(eventName, payload);
} }
dispose() { private _handleFrameTree(frameTree: Protocol.Page.FrameResourceTree) {
helper.removeEventListeners(this._sessionListeners); assert(!frameTree.frame.parentId);
this._mainFrameId = frameTree.frame.id;
} }
} }