fix(filechooser): intercept file choosers lazily (#776)

Fixes #764
This commit is contained in:
Pavel Feldman 2020-01-30 17:43:06 -08:00 committed by GitHub
parent 985faebd12
commit b289bb790b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 35 additions and 9 deletions

View File

@ -94,7 +94,6 @@ export class CRPage implements PageDelegate {
this._handleFrameTree(frameTree);
const promises: Promise<any>[] = [
this._client.send('Log.enable', {}),
this._client.send('Page.setInterceptFileChooserDialog', {enabled: true}),
this._client.send('Page.setLifecycleEventsEnabled', { enabled: true }),
this._client.send('Runtime.enable', {}).then(() => this._ensureIsolatedWorld(UTILITY_WORLD_NAME)),
this._networkManager.initialize(),
@ -346,6 +345,10 @@ export class CRPage implements PageDelegate {
await this._networkManager.authenticate(credentials);
}
async setFileChooserIntercepted(enabled: boolean) {
await this._client.send('Page.setInterceptFileChooserDialog', { enabled }).catch(e => {}); // target can be closed.
}
async reload(): Promise<void> {
await this._client.send('Page.reload');
}

View File

@ -79,7 +79,6 @@ export class FFPage implements PageDelegate {
this._session.send('Runtime.enable').then(() => this._ensureIsolatedWorld(UTILITY_WORLD_NAME)),
this._session.send('Network.enable'),
this._session.send('Page.enable'),
this._session.send('Page.setInterceptFileChooserDialog', { enabled: true })
];
const options = this._page.browserContext()._options;
if (options.viewport)
@ -306,6 +305,10 @@ export class FFPage implements PageDelegate {
await this._session.send('Network.setAuthCredentials', credentials || { username: null, password: null });
}
async setFileChooserIntercepted(enabled: boolean) {
await this._session.send('Page.setInterceptFileChooserDialog', { enabled }).catch(e => {}); // target can be closed.
}
async reload(): Promise<void> {
await this._session.send('Page.reload', { frameId: this._page.mainFrame()._id });
}

View File

@ -50,6 +50,7 @@ export interface PageDelegate {
setRequestInterception(enabled: boolean): Promise<void>;
setOfflineMode(enabled: boolean): Promise<void>;
authenticate(credentials: types.Credentials | null): Promise<void>;
setFileChooserIntercepted(enabled: boolean): Promise<void>;
getBoundingBoxForScreenshot(handle: dom.ElementHandle<Node>): Promise<types.Rect | null>;
canScreenshotOutsideViewport(): boolean;
@ -120,7 +121,7 @@ export class Page extends platform.EventEmitter {
colorScheme: null,
extraHTTPHeaders: null,
credentials: null,
hasTouch: null
hasTouch: null,
};
this.accessibility = new accessibility.Accessibility(delegate.getAccessibilityTree.bind(delegate));
this.keyboard = new input.Keyboard(delegate.rawKeyboard);
@ -490,6 +491,22 @@ export class Page extends platform.EventEmitter {
this._workers.delete(workerId);
}
}
on(event: string | symbol, listener: platform.Listener): this {
if (event === Events.Page.FileChooser) {
if (!this.listenerCount(event))
this._delegate.setFileChooserIntercepted(true);
}
super.on(event, listener);
return this;
}
removeListener(event: string | symbol, listener: platform.Listener): this {
super.removeListener(event, listener);
if (event === Events.Page.FileChooser && !this.listenerCount(event))
this._delegate.setFileChooserIntercepted(false);
return this;
}
}
export class Worker {

View File

@ -51,13 +51,13 @@ export function promisify(nodeFunction: Function): Function {
return promisified;
}
type Listener = (...args: any[]) => void;
export type Listener = (...args: any[]) => void;
export const EventEmitter: typeof nodeEvents.EventEmitter = isNode ? nodeEvents.EventEmitter : (
class EventEmitterImpl {
private _deliveryQueue?: {listener: Listener, args: any[]}[];
private _listeners = new Map<string | symbol, Set<Listener>>();
addListener(event: string | symbol, listener: Listener): this {
on(event: string | symbol, listener: Listener): this {
let set = this._listeners.get(event);
if (!set) {
set = new Set();
@ -67,8 +67,8 @@ export const EventEmitter: typeof nodeEvents.EventEmitter = isNode ? nodeEvents.
return this;
}
on(event: string | symbol, listener: Listener): this {
return this.addListener(event, listener);
addListener(event: string | symbol, listener: Listener): this {
return this.on(event, listener);
}
once(event: string | symbol, listener: Listener): this {
@ -76,7 +76,7 @@ export const EventEmitter: typeof nodeEvents.EventEmitter = isNode ? nodeEvents.
this.removeListener(event, wrapped);
listener(...args);
};
return this.on(event, wrapped);
return this.addListener(event, wrapped);
}
removeListener(event: string | symbol, listener: Listener): this {

View File

@ -117,7 +117,6 @@ export class WKPage implements PageDelegate {
session.send('Runtime.enable'),
session.send('Page.createUserWorld', { name: UTILITY_WORLD_NAME }).catch(_ => {}), // Worlds are per-process
session.send('Console.enable'),
session.send('Page.setInterceptFileChooserDialog', { enabled: true }),
session.send('Network.enable'),
this._workers.initializeSession(session)
];
@ -423,6 +422,10 @@ export class WKPage implements PageDelegate {
await this._pageProxySession.send('Emulation.setAuthCredentials', { ...(credentials || { username: '', password: '' }) });
}
async setFileChooserIntercepted(enabled: boolean) {
await this._session.send('Page.setInterceptFileChooserDialog', { enabled }).catch(e => {}); // target can be closed.
}
async reload(): Promise<void> {
await this._session.send('Page.reload');
}