presentation/renderers/page.shell.renderer.ts
presentation/renderers/page.shell.renderer.ts is a file in Bane's Lab Site. 76 lines of code and 16 definitions.
import { MISSING_PAGE_LINK, MISSING_PAGE_MESSAGE, MISSING_PAGE_TITLE } from "#configuration/strings/page.strings";
import type { RecordLink, SectionSubject } from "#types/page.types";
import { COPY_PAGE_TITLE } from "#configuration/strings/clipboard.strings";
import { HOME_PAGE } from "#core/ids/page.ids";
import { STATIC_RENDER_ATTRIBUTE } from "#configuration/constants/document.constants";
import { createCopyButton } from "#presentation/components/clipboard.component";
import { createElement } from "#core/factories/element.factory";
import { createPageLink } from "#presentation/components/link.component";
import { exportText } from "#core/converters/text.converter";
import { loadedPage } from "#domain/registries/page.registry";
import { missingSection } from "#configuration/strings/report.strings";
import { renderOwnSection } from "#presentation/renderers/tab.renderer";
import { renderSiteFooter } from "#presentation/renderers/site.renderer";
import { secondaryTab } from "#presentation/renderers/page.renderer";
const missingPage = function missingPage(): Element {
return createElement("div", {
children: [
createElement("h1", { text: MISSING_PAGE_TITLE }),
createElement("p", { text: MISSING_PAGE_MESSAGE }),
createPageLink(HOME_PAGE, "footer-link", [MISSING_PAGE_LINK]),
],
className: "missing-page",
});
};
const asStatic = function asStatic<Result>(work: () => Result): Result {
document.documentElement.setAttribute(STATIC_RENDER_ATTRIBUTE, "");
try {
return work();
} finally {
document.documentElement.removeAttribute(STATIC_RENDER_ATTRIBUTE);
}
};
export const renderPage = function renderPage(page: string): readonly Element[] {
const definition = loadedPage(page);
const content = definition === undefined ? missingPage() : definition.render();
const shell = createElement("div", { children: [content], className: "page-content" });
shell.append(createCopyButton(() => exportText(shell), "copy-button large copy-all", COPY_PAGE_TITLE));
return [shell, renderSiteFooter(definition?.license)];
};
export const renderStaticPage = function renderStaticPage(page: string): readonly Element[] {
return asStatic(() => renderPage(page));
};
const linkOf = function linkOf(link: RecordLink): Element {
return createElement("a", { attributes: { href: link.path ?? "" }, text: link.label });
};
export const renderSectionPage = function renderSectionPage(subject: SectionSubject): Element {
const { seed } = subject;
const definition = loadedPage(seed.page);
const content = definition?.content.kind === "tabbed" ? definition.content : null;
const tab = content?.tabs.find((candidate) => candidate.id === seed.tab);
const draw = (): Element | null =>
content === null || tab === undefined ? null : renderOwnSection(content.layout, tab, seed.section, seed.rows);
const group = asStatic(draw);
if (group === null) {
throw new Error(missingSection(seed.page, seed.tab, seed.section));
}
const parts = subject.parts.map((link) => createElement("li", { children: [linkOf(link)] }));
return createElement("article", {
children: [
createElement("nav", { children: [linkOf({ label: seed.tabTitle, path: seed.tabPath })] }),
createElement("h1", { text: seed.tabTitle }),
group,
...(parts.length < 2 ? [] : [createElement("ul", { children: parts, className: "section-parts" })]),
],
className: "section-page",
});
};
export const renderStaticSection = function renderStaticSection(page: string, path: string, id: string): Element | null {
const definition = loadedPage(page);
if (definition?.content.kind !== "tabbed") {
return null;
}
const { layout, tabs } = definition.content;
const tab = secondaryTab(definition, path) ?? tabs[0];
return tab === undefined ? null : asStatic(() => renderOwnSection(layout, tab, id));
};