UNPKG

@difizen/mana-core

Version:

67 lines (58 loc) 2.2 kB
import type { Event } from '@difizen/mana-common'; import { Emitter } from '@difizen/mana-common'; import { singleton } from '@difizen/mana-syringe'; import { ApplicationContribution } from './application'; import type { Application } from './application'; import { WindowService } from './application-protocol'; @singleton({ contrib: [WindowService, ApplicationContribution], }) export class DefaultWindowService implements WindowService, ApplicationContribution { protected frontendApplication?: Application; protected onUnloadEmitter = new Emitter<void>(); get onUnload(): Event<void> { return this.onUnloadEmitter.event; } onStart(app: Application): void { this.frontendApplication = app; this.registerUnloadListeners(); } canUnload(): boolean { // eslint-disable-next-line prefer-const let confirmExit = 'never'; // TODO: core preferrence application.confirmExit let preventUnload = this.frontendApplication?.onWillStop(); preventUnload = confirmExit === 'always' || preventUnload; return confirmExit === 'never' || !preventUnload; } /** * Implement the mechanism to detect unloading of the page. */ protected registerUnloadListeners(): void { window.addEventListener('beforeunload', (event) => { if (!this.canUnload()) { return this.preventUnload(event); } return undefined; }); // In a browser, `unload` is correctly fired when the page unloads, unlike Electron. // If `beforeunload` is cancelled, the user will be prompted to leave or stay. // If the user stays, the page won't be unloaded, so `unload` is not fired. // If the user leaves, the page will be unloaded, so `unload` is fired. window.addEventListener('unload', () => this.onUnloadEmitter.fire()); } /** * Notify the browser that we do not want to unload. * * Notes: * - Shows a confirmation popup in browsers. * - Prevents the window from closing without confirmation in electron. * * @param event The beforeunload event */ protected preventUnload(event: BeforeUnloadEvent): string | void { event.returnValue = ''; event.preventDefault(); return ''; } }