/* examples.js — daslang apps compiled to WebAssembly, played in-browser. * * Each game ships as a standalone wasm64 build (host == target pointer width, * so the cross-compile is layout-correct). The compiled artifacts live at * examples//.{html,js,wasm} * and are loaded into an '; } function openPlayer(ex) { closePlayer(); var needs64 = ex.wasm64Only && !USE_WASM64; var statusText = needs64 ? 'needs memory64' : (USE_WASM64 ? 'loading…' : 'loading · interpreted'); var statusClass = needs64 ? 'is-fallback' : 'is-loading'; var overlay = document.createElement('div'); overlay.className = 'forge-ex-overlay'; overlay.innerHTML = '' + ''; // Backdrop click closes; clicks inside the dialog do not. overlay.addEventListener('click', function (e) { if (e.target === overlay) closePlayer(); }); document.body.appendChild(overlay); activeOverlay = overlay; document.addEventListener('keydown', onKeydown); document.addEventListener('fullscreenchange', onFsChange); var player = overlay.querySelector('.forge-ex-player'); player.addEventListener('click', function (e) { var btn = e.target.closest('[data-act]'); if (!btn) return; var act = btn.getAttribute('data-act'); if (act === 'close') closePlayer(); else if (act === 'restart') { var f = document.getElementById('ex-frame'); if (!f) return; // no iframe (e.g. memory64-only note) — nothing to restart f.src = f.src; setStatus(USE_WASM64 ? 'loading…' : 'loading · interpreted', 'is-loading'); } else if (act === 'fullscreen') { var vp = document.getElementById('ex-viewport'); if (vp && vp.requestFullscreen) vp.requestFullscreen().catch(function () {}); } }); var frame = overlay.querySelector('#ex-frame'); if (frame) { frame.addEventListener('load', function () { setStatus(USE_WASM64 ? 'running' : 'running · interpreted', 'is-running'); // Focus the game canvas inside the iframe so keyboard input flows, and // guard scroll-keys at runtime (belt-and-suspenders with the shell's own // guard — covers any already-deployed card built before that shell). The // game frame is same-origin, so both are reachable. try { frame.contentWindow && frame.contentWindow.focus(); var idoc = frame.contentDocument; var canvas = idoc && idoc.getElementById('canvas'); if (canvas && canvas.focus) canvas.focus(); if (frame.contentWindow) { frame.contentWindow.addEventListener('keydown', function (e) { if (SCROLL_KEYS[e.key]) e.preventDefault(); }, { passive: false }); } } catch (e) {} }); } } function setStatus(text, cls) { var el = document.getElementById('ex-status'); if (!el) return; el.className = 'forge-ex-player__status ' + cls; el.innerHTML = '' + esc(text); } // ─── Deep link (?example=arcanoid / ?g=pacman) ────────────────────── function autoOpenFromQuery() { var q = new URLSearchParams(window.location.search); var slug = q.get('example') || q.get('g'); if (!slug) return; var ex = DAS_EXAMPLES.filter(function (e) { return e.id === slug; })[0]; if (ex) openPlayer(ex); } document.addEventListener('DOMContentLoaded', function () { renderGrid(); autoOpenFromQuery(); }); })();