Error loading site.

${escapeHtml(e)}

`; const DOCUMENT_METADATA_EVENT = "sw-document-metadata"; /*! Only image data URLs and absolute HTTPS URLs cross the sandbox boundary. */ function normalizeDocumentIcon(href) { const value = href.trim(); if (value.toLowerCase().startsWith("data:image/")) return value; try { const url = new URL(value); return url.protocol === "https:" ? url.href : null; } catch { return null; } } function isDocumentMetadata(value) { if (typeof value !== "object" || value === null) return false; const metadata = value; return typeof metadata.title === "string" && (metadata.icon === null || typeof metadata.icon === "string" && normalizeDocumentIcon(metadata.icon) === metadata.icon); } /*! Promote the chosen child's metadata; the document's own icon is its fallback. */ function applyDocumentMetadata(metadata, fallbackTitle, target = document) { target.title = metadata.title.trim() || fallbackTitle; let promoted = target.head.querySelector( 'link[rel="icon"][data-sw-promoted-icon]' ); if (!metadata.icon) { promoted?.remove(); return; } if (!promoted) { promoted = target.createElement("link"); promoted.rel = "icon"; promoted.setAttribute("data-sw-promoted-icon", ""); target.head.append(promoted); } if (promoted.getAttribute("href") !== metadata.icon) { promoted.setAttribute("href", metadata.icon); } } function getBrowserElement() { const element = document.querySelector("sw-transclude"); if (!element) { throw new Error("The browser loader needs a transclude element"); } return element; } function startBrowserLoader() { const browser = getBrowserElement(); browser.addEventListener(DOCUMENT_METADATA_EVENT, (event) => { const metadata = event.detail; if (!isDocumentMetadata(metadata)) return; event.preventDefault(); applyDocumentMetadata(metadata, "Social.Wiki"); }); const graffiti = new window.Graffiti(); let session = null; let initialized = false; let loadVersion = 0; //! The kernel gives the top-level route to this loader. Delegate that same //! query through the loader's transclude to whichever browser it selected. function syncBrowserRoute() { browser.setAttribute("query", window.query); } async function defaultBrowser(signal) { return loadDocument( new URL("browser/index.html", lensesUrl), signal ); } async function publishedBrowser(currentSession) { //! getSiteVersions returns reverse chronological/topological order, so //! find() selects this actor's latest publication. const versions = await getSiteVersions(graffiti, "browser"); const version = versions.find( (candidate) => candidate.actor === currentSession.actor ); if (!version) return null; const media = await graffiti.getMedia( version.value.document, { types: ["text/html"] }, currentSession ); return media.data.text(); } async function loadBrowser() { const version = ++loadVersion; applyDocumentMetadata({ title: "", icon: null }, "Social.Wiki"); try { const html = session ? await publishedBrowser(session) : null; const source = html ?? await defaultBrowser(); if (version !== loadVersion) return; browser.setAttribute("srcdoc", source); syncBrowserRoute(); } catch (error) { console.error("Could not load the personal browser", error); try { const source = await defaultBrowser(); if (version !== loadVersion) return; browser.setAttribute("srcdoc", source); syncBrowserRoute(); } catch (fallbackError) { console.error("Could not load the default browser", fallbackError); if (version !== loadVersion) return; browser.setAttribute( "srcdoc", ErrorPage( `Could not load the browser: ${fallbackError instanceof Error ? fallbackError.message : String(fallbackError)}` ) ); } } } browser.onUnhandledEvent = (event) => window.emit(event.type, event.detail); window.addEventListener("querychange", syncBrowserRoute); graffiti.sessionEvents.addEventListener("login", (event) => { const detail = event.detail; if (detail.error) { console.error(detail.error); return; } session = detail.session; if (initialized) void loadBrowser(); }); graffiti.sessionEvents.addEventListener("logout", (event) => { const detail = event.detail; if (detail.error) { console.error(detail.error); return; } if (session?.actor === detail.actor) session = null; if (initialized) void loadBrowser(); }); graffiti.sessionEvents.addEventListener("initialized", (event) => { const detail = event.detail; if (detail?.error) console.error(detail.error); initialized = true; void loadBrowser(); }); } if (window.top !== window) startBrowserLoader();