1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
(function() {
'use strict';
// Core module bundle loaded synchronously in main.html.
// This loader only handles version cache-busting, splash, terminal init, and optional ext modules.
const LATEST_VER = 'v4.6.80';
const CACHE = '?v=' + LATEST_VER;
const stored = localStorage.getItem('webx11_cache_ver');
if (stored !== LATEST_VER) {
localStorage.setItem('webx11_cache_ver', LATEST_VER);
}
function setSplash(phase, current, total, filename) {
const fill = document.getElementById('splash-progress-fill');
const phaseEl = document.getElementById('splash-phase');
const fileEl = document.getElementById('splash-filename');
if (fill && total > 0) {
fill.style.width = Math.round((current / total) * 100) + '%';
}
if (phaseEl) phaseEl.textContent = phase;
if (fileEl) fileEl.textContent = filename || '';
}
function hideSplash() {
const overlay = document.getElementById('splash-overlay');
if (overlay) {
overlay.classList.add('hidden');
setTimeout(() => { overlay.style.display = 'none'; }, 350);
}
}
function showSplashError(msg) {
const el = document.getElementById('splash-error');
const fill = document.getElementById('splash-progress-fill');
if (el) { el.textContent = msg; el.classList.add('show'); }
if (fill) fill.style.background = 'var(--error-color)';
}
// Create webx11 synchronously so critical-ext-bundle.js (loaded right after us)
// can call registerModule() without waiting for DOMContentLoaded
const webx11 = new WebX11Terminal();
window.webx11 = webx11;
async function init() {
try {
const total = 3;
let count = 0;
setSplash('Core bundle loaded (1/3)', ++count, total, 'core-bundle.js');
setSplash('Critical ext bundle loaded (2/3)', ++count, total, 'critical-ext-bundle.js');
setSplash('Initializing terminal (3/3)', total, total, '');
// webx11 already created synchronously above — just init ext modules
if (typeof webx11._loadExtModules === 'function') {
let extKeys = ['calc', 'voice', 'debug-panel', 'cron', 'theme', 'wpm', 'mindmap', 'webdav', 'skill-pack-core', 'cryptogzip', 'tutorial', 'floating', 'console', 'media', 'three', 'kanban', 'course'];
const saved = localStorage.getItem('webx11_startup_modules');
let selected = null;
try { if (saved) selected = JSON.parse(saved); } catch (e) {}
if (selected && Array.isArray(selected)) {
extKeys = extKeys.filter(k => selected.includes(k + '.js'));
}
let disabledMods = [];
try { disabledMods = JSON.parse(localStorage.getItem('webx11_module_disabled') || '[]'); } catch (e) {}
extKeys = extKeys.filter(k => !disabledMods.includes(k));
if (extKeys.length > 0) {
setTimeout(() => webx11._loadExtModules(extKeys), 800);
}
}
hideSplash();
console.log('[ModuleLoader] Core loader initialized');
} catch (err) {
console.error('[ModuleLoader] Fatal error:', err);
showSplashError('Loading failed — ' + err.message);
}
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();
|