feat: full de-Angularization with Bootstrap 5 migration
- Removed AngularJS 1.4.8 completely — no more framework dependency - Extracted core RCON logic into pure vanilla JS (js/rcon.js) - Added lightweight hash-based SPA router (js/router.js) - Rewrote all 6 pages as vanilla JS modules in js/pages/ - Migrated Bootstrap 3 → Bootstrap 5 (cards instead of panels, bootstrap-icons instead of glyphicons) - Removed jQuery dependency (Bootstrap 5 is vanilla JS) - Purged all Angular templates from html/ - Removed npm artifacts (package.json, node_modules) - Added nginx.example.conf for static hosting - Updated rcon.css dark theme for BS5 variables - Static file only — no Node.js backend required Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* Minimal hash-based SPA router.
|
||||
*
|
||||
* Route format: { pattern: RegExp, title: string, template: string, onEnter: function(params, container) }
|
||||
*
|
||||
* The first matching route's onEnter is called with parsed params and a container element.
|
||||
* The container is cleared before each navigation.
|
||||
*
|
||||
* Usage:
|
||||
* Router.add(/^\/(.+)\/info$/, 'Server', 'html/serverInfo.html', ServerInfoPage);
|
||||
* Router.add(/^\/(.+)\/player\/(.+)$/, 'Player Info', 'html/playerInfo.html', PlayerInfoPage);
|
||||
* Router.start('#app-view');
|
||||
*/
|
||||
var Router = (function () {
|
||||
'use strict';
|
||||
|
||||
var routes = [];
|
||||
var viewSelector = null;
|
||||
var currentCleanup = null;
|
||||
|
||||
function add(pattern, title, template, onEnter) {
|
||||
routes.push({ pattern: pattern, title: title, template: template, onEnter: onEnter });
|
||||
}
|
||||
|
||||
function navigate(hash) {
|
||||
// strip leading # and optional /
|
||||
var path = (hash || '').replace(/^#\/?/, '/');
|
||||
if (!path || path === '/') path = '/home';
|
||||
|
||||
for (var i = 0; i < routes.length; i++) {
|
||||
var r = routes[i];
|
||||
var match = path.match(r.pattern);
|
||||
if (match) {
|
||||
// Store params for later use
|
||||
var container = document.querySelector(viewSelector);
|
||||
if (!container) return;
|
||||
|
||||
// Cleanup previous page
|
||||
if (currentCleanup && typeof currentCleanup === 'function') {
|
||||
currentCleanup();
|
||||
currentCleanup = null;
|
||||
}
|
||||
|
||||
// Clear container
|
||||
container.innerHTML = '';
|
||||
|
||||
// Call onEnter with match groups + container
|
||||
if (typeof r.onEnter === 'function') {
|
||||
var result = r.onEnter(match, container);
|
||||
if (typeof result === 'function') {
|
||||
currentCleanup = result;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function start(selector) {
|
||||
viewSelector = selector;
|
||||
window.addEventListener('hashchange', function () {
|
||||
navigate(window.location.hash);
|
||||
});
|
||||
// Initial navigation
|
||||
if (window.location.hash) {
|
||||
navigate(window.location.hash);
|
||||
}
|
||||
}
|
||||
|
||||
function go(hash) {
|
||||
window.location.hash = hash;
|
||||
}
|
||||
|
||||
return {
|
||||
add: add,
|
||||
start: start,
|
||||
go: go,
|
||||
navigate: navigate
|
||||
};
|
||||
})();
|
||||
Reference in New Issue
Block a user