← Commit history

Chaitan nameplate: self-hosted 3D viewer, Z-up model, README.html

John Lauer ·f4392a8cca ·3mo ago ·parent 1e5a8ea
2 files changed +24−17
README.html+5−5
@@ -2,9 +2,9 @@ <meta name="readme-max-height" content="32000"> <meta name="viewport" content="width=device-width, initial-scale=1"> <style>-  @font-face { font-family:'Familjen Grotesk';-    src:url('https://adom.inc/fonts/familjen-grotesk/familjen-grotesk-latin-700-normal.woff2') format('woff2');-    font-weight:700; font-display:swap; }+  /* No @font-face here: the wiki renders README.html in a null-origin iframe,+     so adom.inc's font files fail CORS on every load and only add console+     noise. Fall back to the system stack, which the wiki chrome matches. */   :root { --bg:#0d1117; --surface:#161b22; --elev:#1c2128; --border:#30363d;            --text:#e6edf3; --body:#c9d1d9; --muted:#8b949e; --accent:#00b8b1; --purple:#8C6BF7; }   * { box-sizing:border-box; margin:0; padding:0; }@@ -13,9 +13,9 @@     scrollbar-width:none; }   html::-webkit-scrollbar, body::-webkit-scrollbar { width:0; height:0; display:none; }   #wrap { max-width:900px; margin:0 auto; padding:24px 20px 48px; }-  h1 { font-family:'Familjen Grotesk',sans-serif; font-weight:700; color:var(--text);+  h1 { font-weight:700; color:var(--text);         font-size:40px; letter-spacing:-.02em; margin:6px 0 4px; }-  h2 { font-family:'Familjen Grotesk',sans-serif; font-weight:700; color:var(--text);+  h2 { font-weight:700; color:var(--text);         font-size:24px; margin:36px 0 10px; letter-spacing:-.01em; }   p { margin:10px 0; }   .lede { color:var(--muted); font-size:17px; margin-bottom:20px; }
viewer/index.html+19−12
@@ -1296,9 +1296,19 @@ function loadAlphabet() { }  function loadAdom3D() {-  // The wiki refuses to serve files over ~4 MB (413), and this bundle is 13 MB,-  // so it ships as 4 byte-exact parts. Reassemble as bytes, never as text: a-  // multi-byte character can straddle a split boundary.+  // Two wiki constraints shape this.+  //+  // 1. The render endpoint 413s on files over ~4 MB and this bundle is 13 MB,+  //    so it ships as 4 byte-exact parts, reassembled as bytes (never as+  //    text) because a multi-byte character can straddle a split boundary.+  //+  // 2. The page CSP is `script-src 'unsafe-inline' https:`. That permits an+  //    INLINE script but blocks `blob:`, so handing the reassembled bundle to+  //    URL.createObjectURL and setting script.src fails with+  //    "Loading the script 'blob:null/...' violates ... Content Security+  //    Policy". Setting textContent runs it under 'unsafe-inline' instead.+  //    An inline script executes synchronously on append, so there is nothing+  //    to await once it is in the DOM.   return (async () => {     const N = 4;     const bufs = [];@@ -1312,15 +1322,12 @@ function loadAdom3D() {     const all = new Uint8Array(total);     let o = 0;     for (const b of bufs) { all.set(b, o); o += b.length; }-    const url = URL.createObjectURL(new Blob([all], { type: 'text/javascript' }));-    await new Promise((res, rej) => {-      const s = document.createElement('script');-      s.src = url;-      s.onload = res;-      s.onerror = () => rej(new Error('viewer bundle failed to execute'));-      document.head.appendChild(s);-    });-    URL.revokeObjectURL(url);++    const s = document.createElement('script');+    s.textContent = new TextDecoder('utf-8').decode(all);+    document.head.appendChild(s);++    if (!window.Adom3DViewer) throw new Error('viewer bundle ran but exposed no Adom3DViewer');   })(); }