Wegwichtel/public/js/bootstrap-loader.js

104 lines
3.8 KiB
JavaScript

(function () {
'use strict';
const versions = Object.freeze({ app: '0.12.11', jquery: '4.0.0', jqueryUi: '1.14.2' });
const steps = ['jquery', 'jquery-ui', 'modules', 'server', 'routes', 'location'];
const progress = document.getElementById('bootstrap-progress');
const errorBox = document.getElementById('bootstrap-error');
const retry = document.getElementById('bootstrap-retry');
const versioned = path => `${path}${path.includes('?') ? '&' : '?'}v=${encodeURIComponent(versions.app)}`;
function mark(step, state) {
const item = document.querySelector(`[data-step="${step}"]`);
if (!item) return;
item.classList.remove('done', 'failed');
item.classList.add(state);
progress.value = document.querySelectorAll('#bootstrap-steps .done').length;
}
function loadScript(src, test) {
return new Promise((resolve, reject) => {
const script = document.createElement('script');
script.src = versioned(src);
script.async = false;
script.onload = () => {
if (test && !test()) reject(new Error(`Selbsttest fehlgeschlagen: ${src}`));
else resolve();
};
script.onerror = () => reject(new Error(`Datei konnte nicht geladen werden: ${src}`));
document.head.appendChild(script);
});
}
function loadStyle(href) {
return new Promise((resolve, reject) => {
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = versioned(href);
link.onload = resolve;
link.onerror = () => reject(new Error(`Stylesheet konnte nicht geladen werden: ${href}`));
document.head.appendChild(link);
});
}
function initializeJqueryUi() {
const $ = globalThis.jQuery;
$('#bootstrap-retry').button({ icon: 'ui-icon-refresh' });
$('.back-button').button();
$('#clear-route-search').button({ icon: 'ui-icon-close', showLabel: false });
$('#slide-prev').button();
$('#slide-next').button();
}
async function boot() {
errorBox.hidden = true;
retry.hidden = true;
try {
await loadScript(
`vendor/jquery/jquery-${versions.jquery}.min.js`,
() => globalThis.jQuery?.fn?.jquery === versions.jquery
);
mark('jquery', 'done');
await loadStyle(`vendor/jquery-ui/jquery-ui-${versions.jqueryUi}.min.css`);
await loadStyle('css/app.css');
await loadScript(
`vendor/jquery-ui/jquery-ui-${versions.jqueryUi}.min.js`,
() => globalThis.jQuery?.ui?.version === versions.jqueryUi
);
initializeJqueryUi();
mark('jquery-ui', 'done');
for (const module of ['config', 'api-client', 'distance', 'geolocation', 'orientation', 'slideshow', 'audio-player', 'vibration', 'app']) {
await loadScript(`js/${module}.js`, () => Boolean(globalThis.Wegwichtel));
}
mark('modules', 'done');
await globalThis.Wegwichtel.App.initialize({ markStep: mark });
document.getElementById('bootstrap-screen').hidden = true;
document.getElementById('app-shell').hidden = false;
globalThis.Wegwichtel.App.navigate('#routes-page', { replace: true });
} catch (error) {
console.error(error);
const current = steps.find(step => !document.querySelector(`[data-step="${step}"]`)?.classList.contains('done'));
if (current) mark(current, 'failed');
errorBox.textContent = error.message;
errorBox.hidden = false;
retry.hidden = false;
}
}
function retryBoot(event) {
if (event.type === 'keydown' && event.key !== 'Enter' && event.key !== ' ') return;
if (event.type === 'pointerup' && event.pointerType === 'mouse' && event.button !== 0) return;
event.preventDefault();
location.reload();
}
retry.addEventListener('pointerup', retryBoot);
retry.addEventListener('keydown', retryBoot);
boot();
}());