100 lines
2.8 KiB
TypeScript
100 lines
2.8 KiB
TypeScript
import { PageListType } from "./PageListType";
|
|
import { PageType } from "./PageType";
|
|
|
|
const PageDoesNotExistError = new Error("Page does not exist.");
|
|
const PageHasNotBeenSetError = new Error("Page has not been set.");
|
|
|
|
export type Options = {
|
|
pageList: PageListType;
|
|
state: unknown;
|
|
pageContentElement: HTMLElement;
|
|
pageTitleElement: HTMLElement;
|
|
resetElementContent?: boolean;
|
|
onPageChange: () => void;
|
|
};
|
|
|
|
export class PageRouter {
|
|
constructor(options: Options) {
|
|
this.pageList = options.pageList;
|
|
this.state = options.state;
|
|
this.pageContentElement = options.pageContentElement;
|
|
this.pageTitleElement = options.pageTitleElement;
|
|
this.resetElementContent = (options.resetElementContent || true) == true;
|
|
this.onPageChange = options.onPageChange;
|
|
}
|
|
|
|
public onPageChange: () => void;
|
|
|
|
private pageList: PageListType;
|
|
private currentPageID: string;
|
|
private currentPage: PageType;
|
|
|
|
private resetElementContent: boolean;
|
|
|
|
public state: unknown;
|
|
public pageContentElement: HTMLElement;
|
|
public pageTitleElement: HTMLElement;
|
|
|
|
public async getPageIDs(): Promise<string[]> {
|
|
return await this.pageList.getPageIDs();
|
|
}
|
|
|
|
public async getCurrentPage(): Promise<PageType> {
|
|
return this.currentPage;
|
|
}
|
|
|
|
public async getCurrentPageID(): Promise<string> {
|
|
return this.currentPageID;
|
|
}
|
|
|
|
public async setPageContent(content: string | HTMLElement): Promise<void> {
|
|
if (typeof content === "string") {
|
|
this.pageContentElement.innerHTML = content;
|
|
} else {
|
|
this.pageContentElement.innerHTML = "";
|
|
this.pageContentElement.appendChild(content);
|
|
}
|
|
}
|
|
|
|
public async changePage(pageID: string): Promise<void> {
|
|
if (!(await this.getPageIDs()).includes(pageID)) throw PageDoesNotExistError;
|
|
|
|
// Do cleanup on current page.
|
|
if (this.currentPage) {
|
|
await this.currentPage.cleanup();
|
|
}
|
|
|
|
// Set the current page to the new page
|
|
this.currentPageID = pageID;
|
|
this.currentPage = await this.pageList.getPage(pageID);
|
|
|
|
// Dispatch an event saying the page has been changed.
|
|
this.onPageChange();
|
|
|
|
await this.currentPage.setRouterAndState(this, this.state);
|
|
|
|
// Render the page.
|
|
await this.renderPage();
|
|
}
|
|
|
|
public async renderPage(): Promise<void> {
|
|
if (!this.currentPage) throw PageHasNotBeenSetError;
|
|
|
|
if (this.resetElementContent) {
|
|
// Reset back to blank.
|
|
this.pageContentElement.innerHTML = "";
|
|
this.pageTitleElement.innerHTML = "";
|
|
}
|
|
await Promise.all([this.currentPage.renderPageTitle(), this.currentPage.render()]);
|
|
}
|
|
|
|
public async refresh(): Promise<void> {
|
|
await this.renderPage();
|
|
}
|
|
|
|
public async goBack(): Promise<void> {
|
|
if (!this.currentPage) throw PageHasNotBeenSetError;
|
|
await this.currentPage.goBack();
|
|
}
|
|
}
|