UNPKG

@malagu/core

Version:
145 lines • 5.99 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.FrontendApplication = void 0; const shell_1 = require("../shell"); const frontend_application_state_1 = require("./frontend-application-state"); const browser_1 = require("../browser"); const common_1 = require("../../common"); let FrontendApplication = class FrontendApplication extends common_1.AbstractApplication { get shell() { return this._shell; } async start() { await this.doStart(); this.stateService.state = 'started'; const host = await this.getHost(); this._shell.attach(host); await new Promise(resolve => requestAnimationFrame(() => resolve())); this.stateService.state = 'attached_shell'; await this.revealShell(host); this.registerEventListeners(); this.stateService.state = 'ready'; } /** * Return a promise to the host element to which the application shell is attached. */ getHost() { if (document.body) { return Promise.resolve(document.getElementById(this.hostDomId) || document.body); } return new Promise(resolve => window.addEventListener('load', () => resolve(document.getElementById(this.hostDomId) || document.body), { once: true })); } /** * Return an HTML element that indicates the startup phase, e.g. with an animation or a splash screen. */ getStartupIndicator(host) { const startupElements = host.getElementsByClassName('malagu-preload'); return startupElements.length === 0 ? undefined : startupElements[0]; } /** * Register global event listeners. */ registerEventListeners() { window.addEventListener('unload', () => { this.stateService.state = 'closing_window'; this.doStop(); }); } /** * If a startup indicator is present, it is first hidden with the `malagu-hidden` CSS class and then * removed after a while. The delay until removal is taken from the CSS transition duration. */ revealShell(host) { const startupElem = this.getStartupIndicator(host); if (startupElem) { return new Promise(resolve => { window.requestAnimationFrame(() => { startupElem.classList.add('malagu-hidden'); const preloadStyle = window.getComputedStyle(startupElem); const transitionDuration = (0, browser_1.parseCssTime)(preloadStyle.transitionDuration, 0); window.setTimeout(() => { const parent = startupElem.parentElement; if (parent) { parent.removeChild(startupElem); } resolve(); }, transitionDuration); }); }); } else { return Promise.resolve(); } } async doStart() { for (const lifecycle of this.lifecycles) { if (lifecycle.initialize) { try { lifecycle.initialize(); } catch (error) { this.logger.error('Could not initialize lifecycle', error); } } } // TODO for (const lifecycle of this.lifecycles) { if (lifecycle.onStart) { try { await this.measure(lifecycle.constructor.name + '.onStart', () => lifecycle.onStart(this)); } catch (error) { this.logger.error('Could not start lifecycle', error); } } } } async measure(name, fn) { const startMark = name + '-start'; const endMark = name + '-end'; performance.mark(startMark); const result = await fn(); performance.mark(endMark); performance.measure(name, startMark, endMark); for (const item of performance.getEntriesByName(name)) { if (item.duration > 100) { console.warn(item.name + ' is slow, took: ' + item.duration + ' ms'); } else { console.debug(item.name + ' took ' + item.duration + ' ms'); } } performance.clearMeasures(name); return result; } async stop() { this.doStop(); this.stateService.state = 'stoped'; } }; __decorate([ (0, common_1.Autowired)(shell_1.ApplicationShell), __metadata("design:type", Object) ], FrontendApplication.prototype, "_shell", void 0); __decorate([ (0, common_1.Autowired)(common_1.ApplicationStateService), __metadata("design:type", frontend_application_state_1.FrontendApplicationStateService) ], FrontendApplication.prototype, "stateService", void 0); __decorate([ (0, common_1.Value)('malagu.hostDomId'), __metadata("design:type", String) ], FrontendApplication.prototype, "hostDomId", void 0); FrontendApplication = __decorate([ (0, common_1.Component)(common_1.Application) ], FrontendApplication); exports.FrontendApplication = FrontendApplication; //# sourceMappingURL=frontend-application.js.map