/** * Client-side navigation runtime, served at `/__wrnexus/nav.js`. * * Progressive enhancement over normal links: intercepts same-origin `` * clicks, fetches the target page's HTML, swaps the `#app` container in place, * updates history/title/scroll, ensures any framework runtimes the new page * needs are present, and re-hydrates. Anything unexpected (cross-origin, * modified click, non-HTML response, missing `#app`) falls back to a full * browser navigation, so behaviour degrades safely. * * Data "loaders": pages load their data on the server (SSR `api` bindings), so * the fetched HTML already contains fresh data — no separate client loader is * needed. Client-side (`csr`) bindings and reactive scopes re-hydrate after the * swap. Programmatic navigation is exposed as `window.__wrnexusNavigate(url)`. */ export const NAV_RUNTIME = String.raw` (function () { if (!window.history || !history.pushState || !window.fetch || !window.DOMParser) return; if (window.__wrnexusNavInstalled) return; window.__wrnexusNavInstalled = true; var APP_ID = "app"; function pathOf(src) { return String(src).split("?")[0]; } function isLocalLink(a) { if (!a || a.hasAttribute("download") || a.hasAttribute("data-no-nav")) return false; if (a.target && a.target !== "_self") return false; if (a.origin !== location.origin) return false; var href = a.getAttribute("href"); if (!href || href.charAt(0) === "#") return false; var rel = (a.getAttribute("rel") || "").toLowerCase(); return rel.indexOf("external") === -1; } function loadedScriptPaths() { var set = {}; document.querySelectorAll("script[src]").forEach(function (s) { var src = s.getAttribute("src"); if (src) set[pathOf(src)] = true; }); return set; } // Append any /__wrnexus/* runtime the incoming page declares but the current // document has not loaded yet. Fresh scripts self-initialise on load. function ensureScripts(doc) { var loaded = loadedScriptPaths(); doc.querySelectorAll("script[src]").forEach(function (s) { var src = s.getAttribute("src"); if (!src || loaded[pathOf(src)]) return; loaded[pathOf(src)] = true; var el = document.createElement("script"); el.src = src; el.async = false; // preserve execution order (e.g. schemas.js before validate.js) document.body.appendChild(el); }); } // Re-hydrate already-loaded runtimes against the swapped-in DOM. Every // entrypoint is idempotent, so this is safe even when a fresh script also // self-initialises the same nodes. function rehydrate() { try { if (window.__wrnexusHydrateScopes) window.__wrnexusHydrateScopes(document); } catch (e) {} try { if (window.__wrnexusHydrateCsrFetches) window.__wrnexusHydrateCsrFetches(document); } catch (e) {} try { if (window.__wireValidate) window.__wireValidate.init(document); } catch (e) {} } function render(html, url, isPop) { var doc = new DOMParser().parseFromString(html, "text/html"); var to = doc.getElementById(APP_ID); var from = document.getElementById(APP_ID); if (!to || !from) { location.href = url; return; } // structure mismatch → hard nav if (doc.title) document.title = doc.title; // Swap #app by importing nodes — NOT innerHTML — so it works under a strict // Trusted-Types CSP (require-trusted-types-for 'script'). var imported = []; for (var i = 0; i < to.childNodes.length; i++) imported.push(document.importNode(to.childNodes[i], true)); from.replaceChildren.apply(from, imported); ensureScripts(doc); rehydrate(); if (!isPop) { history.pushState({ wrnexusNav: true }, "", url); window.scrollTo(0, 0); } try { window.dispatchEvent(new CustomEvent("wrnexus:navigated", { detail: { url: url } })); } catch (e) {} } var inFlight = null; function navigate(url, isPop) { var token = {}; inFlight = token; fetch(url, { headers: { "x-wrnexus-nav": "1", accept: "text/html" }, credentials: "same-origin" }) .then(function (r) { if (inFlight !== token) return null; // superseded by a newer navigation if (r.redirected && r.url) url = r.url; // follow server redirects (e.g. auth) var ct = r.headers.get("content-type") || ""; if (ct.indexOf("text/html") === -1) { location.href = url; return null; } return r.text().then(function (t) { if (inFlight === token) render(t, url, isPop); }); }) .catch(function () { location.href = url; }); } document.addEventListener( "click", function (e) { if (e.defaultPrevented || e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return; var a = e.target && e.target.closest ? e.target.closest("a") : null; if (!isLocalLink(a)) return; if (a.href === location.href) { e.preventDefault(); return; } e.preventDefault(); navigate(a.href, false); }, false, ); window.addEventListener("popstate", function () { navigate(location.href, true); }); // Programmatic navigation for forms/actions and app code. window.__wrnexusNavigate = function (url) { navigate(new URL(url, location.href).href, false); }; })(); `.trim();