1
0
silverbullet/webapp/navigator.ts

56 lines
1.3 KiB
TypeScript
Raw Normal View History

import { safeRun } from "./util";
function encodePageUrl(name: string): string {
return name.replaceAll(" ", "_");
}
function decodePageUrl(url: string): string {
return url.replaceAll("_", " ");
}
2022-03-28 13:25:05 +00:00
export class PathPageNavigator {
navigationResolve?: () => void;
async navigate(page: string, pos?: number) {
window.history.pushState(
{ page, pos },
page,
`/${encodePageUrl(page)}${pos ? "@" + pos : ""}`
);
window.dispatchEvent(new PopStateEvent("popstate"));
2022-03-28 13:25:05 +00:00
await new Promise<void>((resolve) => {
this.navigationResolve = resolve;
});
this.navigationResolve = undefined;
}
2022-03-28 13:25:05 +00:00
subscribe(
pageLoadCallback: (pageName: string, pos: number) => Promise<void>
): void {
const cb = () => {
const gotoPage = this.getCurrentPage();
if (!gotoPage) {
return;
}
safeRun(async () => {
2022-03-28 13:25:05 +00:00
await pageLoadCallback(this.getCurrentPage(), this.getCurrentPos());
if (this.navigationResolve) {
2022-03-28 13:25:05 +00:00
this.navigationResolve();
}
});
};
window.addEventListener("popstate", cb);
cb();
}
getCurrentPage(): string {
2022-03-28 13:25:05 +00:00
let [page] = location.pathname.substring(1).split("@");
return decodePageUrl(page);
}
2022-03-28 13:25:05 +00:00
getCurrentPos(): number {
let [, pos] = location.pathname.substring(1).split("@");
return +pos || 0;
}
}