new system prototype
This commit is contained in:
56
website/js/router.js
Normal file
56
website/js/router.js
Normal file
@ -0,0 +1,56 @@
|
||||
const routes = [];
|
||||
let currentCleanup = null;
|
||||
|
||||
export function addRoute(pattern, handler) {
|
||||
let regex;
|
||||
const paramNames = [];
|
||||
if (pattern instanceof RegExp) {
|
||||
regex = pattern;
|
||||
} else {
|
||||
const parts = pattern.replace(/\/:([^/]+)/g, (_, name) => {
|
||||
paramNames.push(name);
|
||||
return '/([^/]+)';
|
||||
});
|
||||
regex = new RegExp('^' + parts + '$');
|
||||
}
|
||||
routes.push({ regex, paramNames, handler });
|
||||
}
|
||||
|
||||
export function navigate(hash) {
|
||||
window.location.hash = hash;
|
||||
}
|
||||
|
||||
export function currentHash() {
|
||||
return window.location.hash.slice(1) || '/';
|
||||
}
|
||||
|
||||
async function resolve() {
|
||||
if (typeof currentCleanup === 'function') {
|
||||
currentCleanup();
|
||||
currentCleanup = null;
|
||||
}
|
||||
|
||||
const path = currentHash();
|
||||
for (const route of routes) {
|
||||
const match = path.match(route.regex);
|
||||
if (match) {
|
||||
const params = {};
|
||||
route.paramNames.forEach((name, i) => {
|
||||
params[name] = decodeURIComponent(match[i + 1]);
|
||||
});
|
||||
try {
|
||||
currentCleanup = await route.handler(params) || null;
|
||||
} catch (e) {
|
||||
console.error('Route handler error:', e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
// fallback: dashboard
|
||||
navigate('#/');
|
||||
}
|
||||
|
||||
export function startRouter() {
|
||||
window.addEventListener('hashchange', resolve);
|
||||
resolve();
|
||||
}
|
||||
Reference in New Issue
Block a user