Back to OScope
oscope/public/js/router.js
Code
37 lines (33 loc) · 1.25 KB
// Path router: /, /coin/<mint>, /portfolio, /trackers, /wallet/<address>.
const routes = [];
let cleanup = null;
let view = null;
export function route(re, make, nav) { routes.push({ re, make, nav }); }
export function go(path, replace = false) {
if (path === location.pathname + location.search) return;
history[replace ? 'replaceState' : 'pushState'](null, '', path);
mount();
}
export function mount() {
view ||= document.getElementById('view');
if (cleanup) { try { cleanup(); } catch {} cleanup = null; }
view.replaceChildren();
const p = location.pathname;
for (const r of routes) {
const m = p.match(r.re);
if (!m) continue;
for (const a of document.querySelectorAll('[data-nav]')) a.classList.toggle('on', a.dataset.nav === r.nav);
cleanup = r.make(view, ...m.slice(1)) || null;
return;
}
history.replaceState(null, '', '/');
mount();
}
// links marked data-link stay inside the page; ctrl / middle click still open a new tab
document.addEventListener('click', e => {
const a = e.target.closest('a[data-link]');
if (!a || e.defaultPrevented || e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return;
e.preventDefault();
go(a.getAttribute('href'));
});
window.addEventListener('popstate', mount);