@malagu/core
Version:
145 lines • 5.99 kB
JavaScript
;
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