62 lines
1.6 KiB
JavaScript
62 lines
1.6 KiB
JavaScript
const Routes = {
|
|
index: null,
|
|
error: null
|
|
}
|
|
|
|
const Events = {
|
|
entries: { /* eventName: [callbacks], */ },
|
|
history: [ /* { eventName, params, }, */ ],
|
|
}
|
|
|
|
export default {
|
|
react() {
|
|
let path = decodeURI(window.location.pathname);
|
|
if (path === '/') {
|
|
if (! Routes.index) return;
|
|
history.replaceState({}, '', Routes.index);
|
|
return this.react();
|
|
}
|
|
|
|
if (! this.route(path)) {
|
|
if (! Routes.error) this.emit('error');
|
|
else this.goto(Routes.error);
|
|
}
|
|
|
|
this.emit('active');
|
|
},
|
|
route(path) {
|
|
return true;
|
|
},
|
|
start(routes) {
|
|
Object.assign(Routes, routes);
|
|
window.addEventListener("popstate", () => this.react());
|
|
this.react();
|
|
},
|
|
from(event) {
|
|
event.preventDefault();
|
|
this.goto(event.target.href, '');
|
|
},
|
|
goto(url, base = '/') {
|
|
if (! url) throw new Error('invalid path: ', url);
|
|
history.pushState({}, '', base + url);
|
|
this.react();
|
|
},
|
|
emit(event, params) {
|
|
Events.history.unshift({ event, params });
|
|
Events.history.length = Math.min(Events.history.length, 50);
|
|
|
|
Events.entries[event]?.forEach(fn => fn(params));
|
|
},
|
|
on(event, callback) {
|
|
if (! Events.entries[event]) Events.entries[event] = [];
|
|
Events.entries[event]?.push(callback);
|
|
},
|
|
recall(event) {
|
|
return Events.history.find(e => e.event === event);
|
|
},
|
|
cancel(event) {
|
|
let callbacks = Events.entries[event]?.splice(0, 50);
|
|
this.on(event, () => Events.entries[event] = callbacks);
|
|
}
|
|
}
|