← Commit history

THE fix: shim localStorage. A sandboxed null-origin document throws on storage access, the viewer reads it during init, and the rejection silently aborts lights + environment + render loop.

John Lauer ·e60830b9d8 ·2mo ago ·parent 091b225
1 file changed +37−1
viewer/index.html+37−1
@@ -1,6 +1,42 @@ <!DOCTYPE html> <html lang="en">-<head><script>+<head>+<script>+/* ── Sandbox storage shim — MUST run before the viewer bundle ─────────────+   The Adom wiki serves this page with a CSP `sandbox` directive and no+   `allow-same-origin`, so the document has a null origin and ANY touch of+   localStorage/sessionStorage throws:++     SecurityError: Failed to read the 'localStorage' property from 'Window':+     The document is sandboxed and lacks the 'allow-same-origin' flag.++   The viewer bundle reads storage during init. The throw becomes an unhandled+   rejection that aborts the REST of setup, so the scene ends up with meshes+   but no lights, no environmentTexture, no render loop and no camera framing.+   Nothing is logged, and engine.getFps() still returns 60, so it presents as+   "the 3D tab is just blank". Every adom-tsci wiki page has this.++   An in-memory stand-in is enough: the viewer only uses storage for UI+   preferences, which do not need to survive the page.                       */+(function () {+  function shimStorage(name) {+    try { window[name].getItem('__probe'); return false; } catch (e) {}+    var store = new Map();+    var shim = {+      getItem: function (k) { k = String(k); return store.has(k) ? store.get(k) : null; },+      setItem: function (k, v) { store.set(String(k), String(v)); },+      removeItem: function (k) { store.delete(String(k)); },+      clear: function () { store.clear(); },+      key: function (i) { var a = Array.from(store.keys()); return i < a.length ? a[i] : null; }+    };+    Object.defineProperty(shim, 'length', { get: function () { return store.size; } });+    try { Object.defineProperty(window, name, { value: shim, configurable: true }); } catch (e) {}+    return true;+  }+  window.__storageShimmed = shimStorage('localStorage') | shimStorage('sessionStorage');+})();+</script>+<script> (() => {   // adom-tsci static export — see src/cli/export_wiki.rs.   const orig = window.fetch.bind(window);