import { BrowserWindow, BrowserWindowConstructorOptions, LoadURLOptions } from 'electron'; import { promisify } from 'util'; import { ISessionHelper } from '../session/i-session-helper'; import { AppWindow } from './app-window'; import { IUrlAppWindow } from './i-url-app-window'; import { WindowClosedError } from './window-closed-error'; export abstract class UrlAppWindow extends AppWindow implements IUrlAppWindow { protected loadOptions: LoadURLOptions; protected constructor( sessionHelper: ISessionHelper, uri: string, options: BrowserWindowConstructorOptions = {}, loadOptions: LoadURLOptions = {} ) { const securedOptions: BrowserWindowConstructorOptions = { ...options, ...{ webPreferences: { enableRemoteModule: false, nodeIntegration: false, contextIsolation: true, }, }, }; super(sessionHelper, uri, securedOptions); this.loadOptions = loadOptions; } public downloadUrlSafe(url: string, savePath: string, options?: LoadURLOptions): Promise { return new Promise((resolve, reject) => { if (!this._window) { throw new WindowClosedError(); } this._window.webContents.session.once('will-download', (event, item) => { item.setSavePath(savePath); item.once('done', (doneEvent, state) => { switch (state) { case 'completed': resolve(); break; case 'cancelled': case 'interrupted': default: reject(new Error(state)); break; } }); item.on('updated', () => { item.resume(); }); }); void this.loadUrlSafe(url, options); }); } public async loadUrlSafe(url: string, options?: LoadURLOptions): Promise { if (!this._window) { throw new WindowClosedError(); } const waitInterval = 1000; let failedLoad = true; do { await new Promise((resolve) => { if (!this._window) { throw new WindowClosedError(); } this._window.webContents.once('did-navigate', (event, navigationUrl, httpResponseCode) => { failedLoad = HttpCode.BAD_REQUEST <= httpResponseCode; resolve(); }); void this._window.loadURL(url, options); }); if (failedLoad) { await promisify(setTimeout)(waitInterval); } } while (failedLoad); } protected load(window: BrowserWindow): Promise { return window.loadURL(this.uri, this.loadOptions); } }