From c15dc94f8e3b9899270680aaf5d1cb674e66fa95 Mon Sep 17 00:00:00 2001 From: Pavel Feldman Date: Wed, 1 Jul 2020 18:36:09 -0700 Subject: [PATCH] chore(rpc): explicitly create page dispatcher (#2799) --- src/rpc/channels.ts | 3 --- src/rpc/client/browser.ts | 2 +- src/rpc/client/browserContext.ts | 2 +- src/rpc/client/browserServer.ts | 4 ++-- src/rpc/client/channelOwner.ts | 5 +++-- src/rpc/client/connection.ts | 10 ++-------- src/rpc/client/consoleMessage.ts | 4 ++-- src/rpc/client/dialog.ts | 4 ++-- src/rpc/client/download.ts | 4 ++-- src/rpc/client/elementHandle.ts | 2 +- src/rpc/client/frame.ts | 2 +- src/rpc/client/jsHandle.ts | 4 ++-- src/rpc/client/network.ts | 6 +++--- src/rpc/client/page.ts | 12 +++++------- src/rpc/client/worker.ts | 2 +- src/rpc/server/browserContextDispatcher.ts | 4 ++-- src/rpc/server/dispatcher.ts | 9 ++------- src/rpc/server/pageDispatcher.ts | 17 ++++------------- 18 files changed, 36 insertions(+), 60 deletions(-) diff --git a/src/rpc/channels.ts b/src/rpc/channels.ts index 49f18607f0..01d33c30c3 100644 --- a/src/rpc/channels.ts +++ b/src/rpc/channels.ts @@ -20,9 +20,6 @@ import * as types from '../types'; export type Binary = string; export interface Channel extends EventEmitter { - _type: string; - _guid: string; - _object: any; } diff --git a/src/rpc/client/browser.ts b/src/rpc/client/browser.ts index 19083e34a6..c295715def 100644 --- a/src/rpc/client/browser.ts +++ b/src/rpc/client/browser.ts @@ -29,7 +29,7 @@ export class Browser extends ChannelOwner { static from(browser: BrowserChannel): Browser { - return browser._object; + return (browser as any)._object; } static fromNullable(browser: BrowserChannel | null): Browser | null { diff --git a/src/rpc/client/browserContext.ts b/src/rpc/client/browserContext.ts index 2d6bc2170b..4e58b80fd4 100644 --- a/src/rpc/client/browserContext.ts +++ b/src/rpc/client/browserContext.ts @@ -37,7 +37,7 @@ export class BrowserContext extends ChannelOwner { - static from(request: BrowserServerChannel): BrowserServer { - return request._object; + static from(server: BrowserServerChannel): BrowserServer { + return (server as any)._object; } constructor(scope: ConnectionScope, guid: string, initializer: BrowserServerInitializer) { diff --git a/src/rpc/client/channelOwner.ts b/src/rpc/client/channelOwner.ts index fab135ee0f..5c5f3e151c 100644 --- a/src/rpc/client/channelOwner.ts +++ b/src/rpc/client/channelOwner.ts @@ -22,9 +22,11 @@ export abstract class ChannelOwner extends Event readonly _channel: T; readonly _initializer: Initializer; readonly _scope: ConnectionScope; + readonly guid: string; constructor(scope: ConnectionScope, guid: string, initializer: Initializer, isScope?: boolean) { super(); + this.guid = guid; this._scope = isScope ? scope.createChild(guid) : scope; const base = new EventEmitter(); this._channel = new Proxy(base, { @@ -46,8 +48,7 @@ export abstract class ChannelOwner extends Event return (params: any) => scope.sendMessageToServer({ guid, method: String(prop), params }); }, }); - this._channel._object = this; - this._channel._guid = guid; + (this._channel as any)._object = this; this._initializer = initializer; } } diff --git a/src/rpc/client/connection.ts b/src/rpc/client/connection.ts index 21eca97c82..7dd0d62bd1 100644 --- a/src/rpc/client/connection.ts +++ b/src/rpc/client/connection.ts @@ -99,11 +99,8 @@ export class Connection { return payload; if (Array.isArray(payload)) return payload.map(p => this._replaceChannelsWithGuids(p)); - if (payload._guid) - return { guid: payload._guid }; - // TODO: send base64 - if (payload instanceof Buffer) - return payload; + if (payload._object instanceof ChannelOwner) + return { guid: payload._object.guid }; if (typeof payload === 'object') { const result: any = {}; for (const key of Object.keys(payload)) @@ -120,9 +117,6 @@ export class Connection { return payload.map(p => this._replaceGuidsWithChannels(p)); if (payload.guid && this._objects.has(payload.guid)) return this._objects.get(payload.guid)!._channel; - // TODO: send base64 - if (payload instanceof Buffer) - return payload; if (typeof payload === 'object') { const result: any = {}; for (const key of Object.keys(payload)) diff --git a/src/rpc/client/consoleMessage.ts b/src/rpc/client/consoleMessage.ts index ffc940b603..2397e00a7f 100644 --- a/src/rpc/client/consoleMessage.ts +++ b/src/rpc/client/consoleMessage.ts @@ -22,8 +22,8 @@ import { ChannelOwner } from './channelOwner'; import { ConnectionScope } from './connection'; export class ConsoleMessage extends ChannelOwner { - static from(request: ConsoleMessageChannel): ConsoleMessage { - return request._object; + static from(message: ConsoleMessageChannel): ConsoleMessage { + return (message as any)._object; } constructor(scope: ConnectionScope, guid: string, initializer: ConsoleMessageInitializer) { diff --git a/src/rpc/client/dialog.ts b/src/rpc/client/dialog.ts index 773c9952da..3bf39f6e2c 100644 --- a/src/rpc/client/dialog.ts +++ b/src/rpc/client/dialog.ts @@ -19,8 +19,8 @@ import { ConnectionScope } from './connection'; import { ChannelOwner } from './channelOwner'; export class Dialog extends ChannelOwner { - static from(request: DialogChannel): Dialog { - return request._object; + static from(dialog: DialogChannel): Dialog { + return (dialog as any)._object; } constructor(scope: ConnectionScope, guid: string, initializer: DialogInitializer) { diff --git a/src/rpc/client/download.ts b/src/rpc/client/download.ts index e07fccbdb5..b5043f7ef4 100644 --- a/src/rpc/client/download.ts +++ b/src/rpc/client/download.ts @@ -21,8 +21,8 @@ import { ChannelOwner } from './channelOwner'; import { Readable } from 'stream'; export class Download extends ChannelOwner { - static from(request: DownloadChannel): Download { - return request._object; + static from(download: DownloadChannel): Download { + return (download as any)._object; } constructor(scope: ConnectionScope, guid: string, initializer: DownloadInitializer) { diff --git a/src/rpc/client/elementHandle.ts b/src/rpc/client/elementHandle.ts index 8789a858db..89a72d0fae 100644 --- a/src/rpc/client/elementHandle.ts +++ b/src/rpc/client/elementHandle.ts @@ -24,7 +24,7 @@ export class ElementHandle extends JSHandle { readonly _elementChannel: ElementHandleChannel; static from(handle: ElementHandleChannel): ElementHandle { - return handle._object; + return (handle as any)._object; } static fromNullable(handle: ElementHandleChannel | null): ElementHandle | null { diff --git a/src/rpc/client/frame.ts b/src/rpc/client/frame.ts index 2b74e74b12..f962c6f358 100644 --- a/src/rpc/client/frame.ts +++ b/src/rpc/client/frame.ts @@ -43,7 +43,7 @@ export class Frame extends ChannelOwner { _page: Page | undefined; static from(frame: FrameChannel): Frame { - return frame._object; + return (frame as any)._object; } static fromNullable(frame: FrameChannel | null): Frame | null { diff --git a/src/rpc/client/jsHandle.ts b/src/rpc/client/jsHandle.ts index 8ae8e1a2b8..29fecdd580 100644 --- a/src/rpc/client/jsHandle.ts +++ b/src/rpc/client/jsHandle.ts @@ -40,7 +40,7 @@ export class JSHandle extends ChannelOwner { if (value instanceof ChannelOwner) - return { h: pushHandle(value._channel._guid) }; + return { h: pushHandle(value.guid) }; return { fallThrough: value }; }); return { value, guids }; diff --git a/src/rpc/client/network.ts b/src/rpc/client/network.ts index ceff61ceaa..51fbb92fab 100644 --- a/src/rpc/client/network.ts +++ b/src/rpc/client/network.ts @@ -51,7 +51,7 @@ export class Request extends ChannelOwner { _failureText: string | null = null; static from(request: RequestChannel): Request { - return request._object; + return (request as any)._object; } static fromNullable(request: RequestChannel | null): Request | null { @@ -135,7 +135,7 @@ export class Request extends ChannelOwner { export class Route extends ChannelOwner { static from(route: RouteChannel): Route { - return route._object; + return (route as any)._object; } constructor(scope: ConnectionScope, guid: string, initializer: RouteInitializer) { @@ -169,7 +169,7 @@ export type RouteHandler = (route: Route, request: Request) => void; export class Response extends ChannelOwner { static from(response: ResponseChannel): Response { - return response._object; + return (response as any)._object; } static fromNullable(response: ResponseChannel | null): Response | null { diff --git a/src/rpc/client/page.ts b/src/rpc/client/page.ts index 1b522ec2e1..cef8bbf44e 100644 --- a/src/rpc/client/page.ts +++ b/src/rpc/client/page.ts @@ -21,7 +21,7 @@ import { Events } from '../../events'; import { assert, assertMaxArguments, helper, Listener } from '../../helper'; import { TimeoutSettings } from '../../timeoutSettings'; import * as types from '../../types'; -import { BindingCallChannel, BindingCallInitializer, Channel, PageChannel, PageInitializer } from '../channels'; +import { BindingCallChannel, BindingCallInitializer, PageChannel, PageInitializer } from '../channels'; import { ConnectionScope } from './connection'; import { parseError, serializeError } from '../serializers'; import { Accessibility } from './accessibility'; @@ -60,7 +60,7 @@ export class Page extends ChannelOwner { _isPageCall = false; static from(page: PageChannel): Page { - return page._object; + return (page as any)._object; } static fromNullable(page: PageChannel | null): Page | null { @@ -502,7 +502,7 @@ export class Page extends ChannelOwner { export class BindingCall extends ChannelOwner { static from(channel: BindingCallChannel): BindingCall { - return channel._object; + return (channel as any)._object; } constructor(scope: ConnectionScope, guid: string, initializer: BindingCallInitializer) { @@ -537,11 +537,9 @@ export async function waitForEvent(emitter: EventEmitter, event: string, options let callback: (a: any) => void; const result = new Promise(f => callback = f); const listener = helper.addEventListener(emitter, event, param => { - // TODO: do not detect channel by guid. - const object = param && param._guid ? (param as Channel)._object : param; - if (predicate && !predicate(object)) + if (predicate && !predicate(param)) return; - callback(object); + callback(param); helper.removeEventListeners([listener]); }); if (timeout === 0) diff --git a/src/rpc/client/worker.ts b/src/rpc/client/worker.ts index f91ac2291d..b959cdd939 100644 --- a/src/rpc/client/worker.ts +++ b/src/rpc/client/worker.ts @@ -26,7 +26,7 @@ export class Worker extends ChannelOwner { _page: Page | undefined; static from(worker: WorkerChannel): Worker { - return worker._object; + return (worker as any)._object; } constructor(scope: ConnectionScope, guid: string, initializer: WorkerInitializer) { diff --git a/src/rpc/server/browserContextDispatcher.ts b/src/rpc/server/browserContextDispatcher.ts index 19da3279bd..dc99c16a77 100644 --- a/src/rpc/server/browserContextDispatcher.ts +++ b/src/rpc/server/browserContextDispatcher.ts @@ -28,10 +28,10 @@ export class BrowserContextDispatcher extends Dispatcher PageDispatcher.from(scope, p)) + pages: context.pages().map(p => new PageDispatcher(scope, p)) }, true); this._context = context; - context.on(Events.BrowserContext.Page, page => this._dispatchEvent('page', PageDispatcher.from(this._scope, page))); + context.on(Events.BrowserContext.Page, page => this._dispatchEvent('page', new PageDispatcher(this._scope, page))); context.on(Events.BrowserContext.Close, () => { this._dispatchEvent('close'); this._scope.dispose(); diff --git a/src/rpc/server/dispatcher.ts b/src/rpc/server/dispatcher.ts index 722d68ef8f..718dc8a717 100644 --- a/src/rpc/server/dispatcher.ts +++ b/src/rpc/server/dispatcher.ts @@ -15,7 +15,7 @@ */ import { EventEmitter } from 'events'; -import { helper, debugAssert } from '../../helper'; +import { helper, debugAssert, assert } from '../../helper'; import { Channel } from '../channels'; import { serializeError } from '../serializers'; @@ -77,6 +77,7 @@ export class DispatcherScope { } bind(guid: string, arg: Dispatcher) { + assert(!this._dispatchers.has(guid)); this._dispatchers.set(guid, arg); this._connection._dispatchers.set(guid, arg); } @@ -161,9 +162,6 @@ export class DispatcherConnection { return { guid: payload._guid }; if (Array.isArray(payload)) return payload.map(p => this._replaceDispatchersWithGuids(p)); - // TODO: send base64 - if (payload instanceof Buffer) - return payload; if (typeof payload === 'object') { const result: any = {}; for (const key of Object.keys(payload)) @@ -180,9 +178,6 @@ export class DispatcherConnection { return payload.map(p => this._replaceGuidsWithDispatchers(p)); if (payload.guid && this._dispatchers.has(payload.guid)) return this._dispatchers.get(payload.guid); - // TODO: send base64 - if (payload instanceof Buffer) - return payload; if (typeof payload === 'object') { const result: any = {}; for (const key of Object.keys(payload)) diff --git a/src/rpc/server/pageDispatcher.ts b/src/rpc/server/pageDispatcher.ts index 3b5eb04b55..4c565b44b4 100644 --- a/src/rpc/server/pageDispatcher.ts +++ b/src/rpc/server/pageDispatcher.ts @@ -21,7 +21,7 @@ import { Request } from '../../network'; import { Page, Worker } from '../../page'; import * as types from '../../types'; import { BindingCallChannel, BindingCallInitializer, ElementHandleChannel, PageChannel, PageInitializer, ResponseChannel, WorkerInitializer, WorkerChannel, JSHandleChannel, Binary } from '../channels'; -import { Dispatcher, DispatcherScope, lookupDispatcher, lookupNullableDispatcher, existingDispatcher } from './dispatcher'; +import { Dispatcher, DispatcherScope, lookupDispatcher, lookupNullableDispatcher } from './dispatcher'; import { parseError, serializeError } from '../serializers'; import { ConsoleMessageDispatcher } from './consoleMessageDispatcher'; import { DialogDispatcher } from './dialogDispatcher'; @@ -35,16 +35,7 @@ import { FileChooser } from '../../fileChooser'; export class PageDispatcher extends Dispatcher implements PageChannel { private _page: Page; - static from(scope: DispatcherScope, page: Page): PageDispatcher { - const result = existingDispatcher(page); - return result || new PageDispatcher(scope, page); - } - - static fromNullable(scope: DispatcherScope, request: Page | null): PageDispatcher | null { - return request ? PageDispatcher.from(scope, request) : null; - } - - private constructor(scope: DispatcherScope, page: Page) { + constructor(scope: DispatcherScope, page: Page) { super(scope, page, 'page', { mainFrame: FrameDispatcher.from(scope, page.mainFrame()), viewportSize: page.viewportSize() @@ -65,7 +56,7 @@ export class PageDispatcher extends Dispatcher implements page.on(Events.Page.FrameNavigated, frame => this._onFrameNavigated(frame)); page.on(Events.Page.Load, () => this._dispatchEvent('load')); page.on(Events.Page.PageError, error => this._dispatchEvent('pageError', { error: serializeError(error) })); - page.on(Events.Page.Popup, page => this._dispatchEvent('popup', PageDispatcher.from(this._scope, page))); + page.on(Events.Page.Popup, page => this._dispatchEvent('popup', lookupDispatcher(page))); page.on(Events.Page.Request, request => this._dispatchEvent('request', RequestDispatcher.from(this._scope, request))); page.on(Events.Page.RequestFailed, (request: Request) => this._dispatchEvent('requestFailed', { request: RequestDispatcher.from(this._scope, request), @@ -188,7 +179,7 @@ export class PageDispatcher extends Dispatcher implements async accessibilitySnapshot(params: { options: { interestingOnly?: boolean, root?: ElementHandleChannel } }): Promise { return await this._page.accessibility.snapshot({ interestingOnly: params.options.interestingOnly, - root: params.options.root ? params.options.root._object : undefined + root: params.options.root ? (params.options.root as ElementHandleDispatcher)._elementHandle : undefined }); }