2025-11-12 20:58:07 +01:00
|
|
|
/*
|
|
|
|
|
catcrafts.net
|
2026-07-18 23:27:41 +02:00
|
|
|
Copyright (C) 2026 Catcrafts
|
2025-11-12 20:58:07 +01:00
|
|
|
|
2026-07-18 23:27:41 +02:00
|
|
|
The source code of this website is made available for viewing purposes only.
|
2025-11-12 20:58:07 +01:00
|
|
|
No permission is granted to copy, modify, distribute, or create derivative works.
|
|
|
|
|
*/
|
|
|
|
|
|
2026-08-05 04:18:37 +02:00
|
|
|
// Browser-side page chrome and content loading.
|
|
|
|
|
//
|
|
|
|
|
// This partition is the wasm half of the split: it owns the DOM and the VFS,
|
|
|
|
|
// and calls into Catcrafts.Shared for every piece of markup. Nothing in here
|
|
|
|
|
// builds HTML by hand — that all lives in Catcrafts.Shared:Views so the server
|
|
|
|
|
// renders byte-identical pages.
|
|
|
|
|
|
2025-11-12 20:58:07 +01:00
|
|
|
export module Catcrafts:Views;
|
2026-07-18 23:27:41 +02:00
|
|
|
import Crafter.Graphics;
|
2026-08-05 04:18:37 +02:00
|
|
|
import Catcrafts.Shared;
|
2026-07-18 23:27:41 +02:00
|
|
|
import std;
|
2025-11-12 20:58:07 +01:00
|
|
|
using namespace Crafter;
|
|
|
|
|
|
|
|
|
|
export namespace Catcrafts {
|
2026-07-18 23:27:41 +02:00
|
|
|
// Builds the persistent page chrome (header / <main id="main"> / footer)
|
|
|
|
|
// under <body>. Owns the root element for the page's lifetime so its
|
|
|
|
|
// children don't get yanked out of the DOM. Must be called from main()
|
|
|
|
|
// — the Crafter.Graphics Dom bridge is only safe to use after wasm
|
|
|
|
|
// instantiation hands control to user code.
|
2026-08-05 04:18:37 +02:00
|
|
|
//
|
|
|
|
|
// When SSR lands this becomes an adopt step rather than a build step: the
|
|
|
|
|
// chrome will already be in the document and re-creating it would discard
|
|
|
|
|
// server-rendered markup and flash. Keeping chrome construction separate
|
|
|
|
|
// from route rendering is what keeps that change local to this function.
|
2026-07-18 23:27:41 +02:00
|
|
|
void InitializePage();
|
2025-11-12 21:24:23 +01:00
|
|
|
|
2026-07-18 23:27:41 +02:00
|
|
|
// Per-render scratch ref to the <main> content container created by
|
|
|
|
|
// InitializePage(). Looking it up fresh on every call costs one
|
|
|
|
|
// document.getElementById; in return we don't have to thread a long-lived
|
|
|
|
|
// reference across module boundaries.
|
|
|
|
|
inline Dom::HtmlElementPtr MainContent() { return Dom::HtmlElementPtr("main"); }
|
2026-08-05 04:18:37 +02:00
|
|
|
|
|
|
|
|
// Site content, parsed once at startup from the bundle. Crafter.Build
|
|
|
|
|
// copies content/*.json to the bundle root and runtime.js fetches every
|
|
|
|
|
// files.json entry into memory before _start, so the reads behind this are
|
|
|
|
|
// plain synchronous ifstreams that never touch the network.
|
|
|
|
|
const Views::SiteContent& SiteData();
|
|
|
|
|
|
|
|
|
|
// Read a file from the wasm VFS by bundle-root name. Returns empty on
|
|
|
|
|
// failure: a missing content file degrades to an empty section rather than
|
|
|
|
|
// a broken page.
|
|
|
|
|
std::string ReadBundleFile(std::string_view name);
|
|
|
|
|
|
|
|
|
|
// document.title is reachable only through Window::SetTitle, so the router
|
|
|
|
|
// needs a Window to set a per-route title. Rather than thread one through
|
|
|
|
|
// every render call, main() registers the live Window once and the router
|
|
|
|
|
// calls SetDocumentTitle. A null window makes SetDocumentTitle a no-op, so
|
|
|
|
|
// ordering mistakes degrade to a stale title instead of a crash.
|
|
|
|
|
void SetActiveWindow(Window* window);
|
|
|
|
|
void SetDocumentTitle(std::string_view title);
|
|
|
|
|
|
|
|
|
|
// True when the document arrived server-rendered, i.e. InitializePage
|
|
|
|
|
// adopted existing chrome rather than building it.
|
|
|
|
|
//
|
|
|
|
|
// The distinction matters: on an SSR'd page the DOM is already correct for
|
|
|
|
|
// the URL and must not be re-rendered, while on the static fallback shell
|
|
|
|
|
// (served when the backend is down) the app has to render everything
|
|
|
|
|
// itself. Both paths exist, and this is how the router tells them apart.
|
|
|
|
|
bool AdoptedSsr();
|
2025-11-12 20:58:07 +01:00
|
|
|
}
|