Skip to content

Commit

Permalink
fix(filechooser): intercept file choosers lazily
Browse files Browse the repository at this point in the history
  • Loading branch information
pavelfeldman committed Jan 31, 2020
1 parent 985faeb commit 3ed4ca5
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 9 deletions.
5 changes: 4 additions & 1 deletion src/chromium/crPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down Expand Up @@ -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');
}
Expand Down
5 changes: 4 additions & 1 deletion src/firefox/ffPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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 });
}
Expand Down
19 changes: 18 additions & 1 deletion src/page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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 {
Expand Down
10 changes: 5 additions & 5 deletions src/platform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -67,16 +67,16 @@ 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 {
const wrapped = (...args: any[]) => {
this.removeListener(event, wrapped);
listener(...args);
};
return this.on(event, wrapped);
return this.addListener(event, wrapped);
}

removeListener(event: string | symbol, listener: Listener): this {
Expand Down
5 changes: 4 additions & 1 deletion src/webkit/wkPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
];
Expand Down Expand Up @@ -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');
}
Expand Down

0 comments on commit 3ed4ca5

Please sign in to comment.