diff --git a/src/webkit/Browser.ts b/src/webkit/Browser.ts index ad7db9f624..002629b31d 100644 --- a/src/webkit/Browser.ts +++ b/src/webkit/Browser.ts @@ -26,11 +26,11 @@ import { Protocol } from './protocol'; import * as types from '../types'; export class Browser extends EventEmitter { - _defaultViewport: types.Viewport; - private _process: childProcess.ChildProcess; - _connection: Connection; + readonly _defaultViewport: types.Viewport; + private readonly _process: childProcess.ChildProcess; + readonly _connection: Connection; private _closeCallback: () => Promise; - private _defaultContext: BrowserContext; + private readonly _defaultContext: BrowserContext; private _contexts = new Map(); _targets = new Map(); private _eventListeners: RegisteredListener[]; @@ -173,7 +173,7 @@ export class Browser extends EventEmitter { } async _pages(context: BrowserContext): Promise { - const targets = this.targets().filter(target => target.browserContext() === context && target.type() === 'page'); + const targets = this.targets().filter(target => target._browserContext === context && target._type === 'page'); const pages = await Promise.all(targets.map(target => target.page())); return pages.filter(page => !!page); } @@ -185,7 +185,7 @@ export class Browser extends EventEmitter { async _onProvisionalTargetCommitted({oldTargetId, newTargetId}) { const oldTarget = this._targets.get(oldTargetId); const newTarget = this._targets.get(newTargetId); - newTarget._swappedIn(oldTarget, this._connection.session(newTargetId)); + newTarget._swappedIn(oldTarget); } disconnect() { diff --git a/src/webkit/Launcher.ts b/src/webkit/Launcher.ts index 0ea69fbb85..e34c2a0717 100644 --- a/src/webkit/Launcher.ts +++ b/src/webkit/Launcher.ts @@ -131,7 +131,7 @@ export class Launcher { const transport = new PipeTransport(webkitProcess.stdio[3] as NodeJS.WritableStream, webkitProcess.stdio[4] as NodeJS.ReadableStream); connection = new Connection('', transport, slowMo); const browser = new Browser(connection, defaultViewport, webkitProcess, gracefullyCloseWebkit); - await browser._waitForTarget(t => t.type() === 'page'); + await browser._waitForTarget(t => t._type === 'page'); return browser; } catch (e) { killWebKit(); diff --git a/src/webkit/Target.ts b/src/webkit/Target.ts index 4cc7f0df00..5fdf5bcf37 100644 --- a/src/webkit/Target.ts +++ b/src/webkit/Target.ts @@ -15,8 +15,7 @@ * limitations under the License. */ -import { RegisteredListener } from '../helper'; -import { Browser, BrowserContext } from './Browser'; +import { BrowserContext } from './Browser'; import { Page } from './Page'; import { Protocol } from './protocol'; import { isSwappedOutError, TargetSession, TargetSessionEvents } from './Connection'; @@ -24,29 +23,23 @@ import { isSwappedOutError, TargetSession, TargetSessionEvents } from './Connect const targetSymbol = Symbol('target'); export class Target { - private _browserContext: BrowserContext; - _targetId: string; - private _type: 'page' | 'service-worker' | 'worker'; + readonly _browserContext: BrowserContext; + readonly _targetId: string; + readonly _type: 'page' | 'service-worker' | 'worker'; private _pagePromise: Promise | null = null; private _page: Page | null = null; - private _url: string; - _initializedPromise: Promise; - _initializedCallback: (value?: unknown) => void; - _isInitialized: boolean; - _eventListeners: RegisteredListener[]; static fromPage(page: Page): Target { return (page as any)[targetSymbol]; } constructor(targetInfo: Protocol.Target.TargetInfo, browserContext: BrowserContext) { - const {targetId, url, type} = targetInfo; + const {targetId, type} = targetInfo; this._browserContext = browserContext; this._targetId = targetId; this._type = type; /** @type {?Promise} */ this._pagePromise = null; - this._url = url; } _didClose() { @@ -54,26 +47,28 @@ export class Target { this._page._didClose(); } - async _swappedIn(oldTarget: Target, session: TargetSession) { + async _swappedIn(oldTarget: Target) { + if (!oldTarget._pagePromise) + return; this._pagePromise = oldTarget._pagePromise; this._page = oldTarget._page; // Swapped out target should not be accessed by anyone. Reset page promise so that // old target does not close the page on connection reset. oldTarget._pagePromise = null; oldTarget._page = null; - if (this._pagePromise) - this._adoptPage(this._page || await this._pagePromise, session); + await this._adoptPage(); } - private async _adoptPage(page: Page, session: TargetSession) { - this._page = page; - (page as any)[targetSymbol] = this; + private async _adoptPage() { + (this._page as any)[targetSymbol] = this; + const browser = this._browserContext.browser(); + const session = browser._connection.session(this._targetId); session.once(TargetSessionEvents.Disconnected, () => { // Once swapped out, we reset _page and won't call _didDisconnect for old session. - if (this._page === page) - page._didDisconnect(); + if (this._page) + this._page._didDisconnect(); }); - await page._initialize(session).catch(e => { + await this._page._initialize(session).catch(e => { // Swallow initialization errors due to newer target swap in, // since we will reinitialize again. if (!isSwappedOutError(e)) @@ -83,31 +78,18 @@ export class Target { async page(): Promise { if (this._type === 'page' && !this._pagePromise) { - const session = this.browser()._connection.session(this._targetId); + const browser = this._browserContext.browser(); + // Reference local page variable as _page may be + // cleared on swap. + const page = new Page(this._browserContext); + this._page = page; this._pagePromise = new Promise(async f => { - const page = new Page(this._browserContext); - await this._adoptPage(page, session); - if (this.browser()._defaultViewport) - await page.setViewport(this.browser()._defaultViewport); + await this._adoptPage(); + if (browser._defaultViewport) + await page.setViewport(browser._defaultViewport); f(page); }); } return this._pagePromise; } - - url(): string { - return this._url; - } - - type(): 'page' | 'service-worker' | 'worker' { - return this._type; - } - - browser(): Browser { - return this._browserContext.browser(); - } - - browserContext(): BrowserContext { - return this._browserContext; - } }