diff --git a/src/webkit/wkPage.ts b/src/webkit/wkPage.ts index a6af66fa19..36e53d71e5 100644 --- a/src/webkit/wkPage.ts +++ b/src/webkit/wkPage.ts @@ -60,7 +60,7 @@ export class WKPage implements PageDelegate { this._session = undefined as any as WKSession; } - async _initializePageProxySession() { + private async _initializePageProxySession() { const promises : Promise[] = [ this._pageProxySession.send('Dialog.enable'), this._networkManager.initializePageProxySession(this._page._state.credentials) @@ -87,25 +87,29 @@ export class WKPage implements PageDelegate { 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 // 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 promises : Promise[] = [ // Page agent must be enabled before Runtime. - session.send('Page.enable') + session.send('Page.enable'), + session.send('Page.getResourceTree').then(resourceTreeHandler), + // Resource tree should be received before first execution context. + session.send('Runtime.enable'), + session.send('Page.createIsolatedWorld', { name: UTILITY_WORLD_NAME, source: `//# sourceURL=${EVALUATION_SCRIPT_URL}` }), + session.send('Console.enable'), + session.send('Page.setInterceptFileChooserDialog', { enabled: true }), + this._networkManager.initializeSession(session, this._page._state.interceptNetwork, this._page._state.offlineMode), + this._workers.initializeSession(session) ]; - if (!isProvisional) - promises.push(session.send('Page.getResourceTree').then(({frameTree}) => this._handleFrameTree(frameTree))); - promises.push( - // Resource tree should be received before first execution context. - session.send('Runtime.enable'), - session.send('Page.createIsolatedWorld', { name: UTILITY_WORLD_NAME, source: `//# sourceURL=${EVALUATION_SCRIPT_URL}` }), - session.send('Console.enable'), - session.send('Page.setInterceptFileChooserDialog', { enabled: true }), - this._networkManager.initializeSession(session, this._page._state.interceptNetwork, this._page._state.offlineMode), - this._workers.initializeSession(session) - ); const contextOptions = this._page.browserContext()._options; if (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) { - let frame = this._page._frameManager.frame(framePayload.id); - const newProcessMainFrame = !frame && !framePayload.parentId; - if (newProcessMainFrame) - frame = this._page._frameManager.mainFrame(); + const frame = this._page._frameManager.frame(framePayload.id); for (const [contextId, context] of this._contextIdToContext) { if (context.frame === frame) { (context._delegate as WKExecutionContext)._dispose(); @@ -201,8 +202,6 @@ export class WKPage implements PageDelegate { frame._contextDestroyed(context); } } - if (newProcessMainFrame) - this._onFrameAttached(framePayload.id, null); this._page._frameManager.frameCommittedNewDocumentNavigation(framePayload.id, framePayload.url, framePayload.name || '', framePayload.loaderId, initial); } diff --git a/src/webkit/wkPageProxy.ts b/src/webkit/wkPageProxy.ts index f30a226b7e..a516145f32 100644 --- a/src/webkit/wkPageProxy.ts +++ b/src/webkit/wkPageProxy.ts @@ -124,10 +124,7 @@ export class WKPageProxy { assert(session, 'One non-provisional target session must exist'); this._wkPage = new WKPage(this._browserContext, this._pageProxySession); this._wkPage.setSession(session!); - await Promise.all([ - this._wkPage._initializePageProxySession(), - this._wkPage._initializeSession(session!), - ]); + await this._wkPage.initialize(); return this._wkPage._page; } @@ -151,7 +148,6 @@ export class WKPageProxy { if (targetInfo.isProvisional && this._wkPage) { assert(!this._provisionalPage); this._provisionalPage = new WKProvisionalPage(session, this._wkPage); - this._wkPage._initializeSession(session); } if (targetInfo.isPaused) this._pageProxySession.send('Target.resume', { targetId: targetInfo.targetId }).catch(debugError); @@ -188,6 +184,7 @@ export class WKPageProxy { oldSession!.errorText = 'Target was swapped out.'; (newSession as any)[isPovisionalSymbol] = undefined; if (this._provisionalPage) { + this._provisionalPage.commit(); this._provisionalPage.dispose(); this._provisionalPage = null; } diff --git a/src/webkit/wkProvisionalPage.ts b/src/webkit/wkProvisionalPage.ts index 318216f293..6e89018e62 100644 --- a/src/webkit/wkProvisionalPage.ts +++ b/src/webkit/wkProvisionalPage.ts @@ -16,12 +16,14 @@ import { WKSession } from './wkConnection'; import { WKPage } from './wkPage'; -import { RegisteredListener, helper } from '../helper'; +import { RegisteredListener, helper, assert } from '../helper'; +import { Protocol } from './protocol'; export class WKProvisionalPage { readonly _session: WKSession; private readonly _wkPage: WKPage; private _sessionListeners: RegisteredListener[] = []; + private _mainFrameId: string | null = null; constructor(session: WKSession, page: WKPage) { this._session = session; @@ -34,7 +36,19 @@ export class WKProvisionalPage { 'Network.loadingFinished', 'Network.loadingFailed', ].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) { // Pretend that the events happened in the same process. if (payload.frameId) @@ -42,7 +56,8 @@ export class WKProvisionalPage { this._wkPage._session.emit(eventName, payload); } - dispose() { - helper.removeEventListeners(this._sessionListeners); + private _handleFrameTree(frameTree: Protocol.Page.FrameResourceTree) { + assert(!frameTree.frame.parentId); + this._mainFrameId = frameTree.frame.id; } } \ No newline at end of file