Skip to content

Commit ffc17b4

Browse files
committed
feat: add #embed route — live demo + raw source side by side
New nav tab shows embed.html running in an iframe on the left, and its complete raw source fetched via fetch() displayed in a <pre> on the right. Both loaded lazily on first navigation. Source has a copy button. https://claude.ai/code/session_014XkyCi4sXUHdDjMstV2Pbt
1 parent fc77672 commit ffc17b4

1 file changed

Lines changed: 52 additions & 0 deletions

File tree

docs/index.html

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ <h1 class="text-xl font-bold text-zinc-900 tracking-tight">✈ iframe-flight</h1
2727
<a href="#" class="nav-link shrink-0 px-4 py-2 text-sm font-semibold border-b-2 border-blue-600 text-blue-700 -mb-px">Demo</a>
2828
<a href="#simple" class="nav-link shrink-0 px-4 py-2 text-sm font-semibold border-b-2 border-transparent text-zinc-500 hover:text-zinc-800 -mb-px transition-colors">Quick start</a>
2929
<a href="#chart" class="nav-link shrink-0 px-4 py-2 text-sm font-semibold border-b-2 border-transparent text-zinc-500 hover:text-zinc-800 -mb-px transition-colors">Visualization</a>
30+
<a href="#embed" class="nav-link shrink-0 px-4 py-2 text-sm font-semibold border-b-2 border-transparent text-zinc-500 hover:text-zinc-800 -mb-px transition-colors">Embed</a>
3031
</nav>
3132

3233
<!-- ══════════════════════════════════════════════
@@ -556,6 +557,44 @@ <h1 class="text-xl font-bold text-zinc-900 tracking-tight">✈ iframe-flight</h1
556557

557558
</div><!-- /page-chart -->
558559

560+
<!-- ══════════════════════════════════════════════
561+
PAGE: EMBED
562+
══════════════════════════════════════════════ -->
563+
<div data-page="embed" hidden>
564+
565+
<p class="text-sm text-zinc-500 mb-4">Single-file pattern — the child iframe is injected via <code class="font-mono text-xs bg-zinc-100 px-1 rounded">srcdoc</code>, no separate HTML file needed. Copy the source and open it directly in a browser.</p>
566+
567+
<div class="grid grid-cols-1 lg:grid-cols-2 gap-4">
568+
569+
<!-- Live demo -->
570+
<div class="bg-white border border-zinc-200 rounded-lg overflow-hidden flex flex-col">
571+
<div class="px-4 py-2.5 bg-zinc-50 border-b border-zinc-200 flex items-center gap-2">
572+
<span class="w-2 h-2 rounded-full bg-green-500 shrink-0"></span>
573+
<span class="text-xs font-semibold text-zinc-500 uppercase tracking-wider">Live</span>
574+
<code class="font-mono text-[11px] text-zinc-400">embed.html</code>
575+
</div>
576+
<iframe id="embed-frame" src="about:blank" class="block w-full flex-1 border-0" style="height:580px"></iframe>
577+
</div>
578+
579+
<!-- Source code -->
580+
<div class="bg-white border border-zinc-200 rounded-lg overflow-hidden flex flex-col">
581+
<div class="px-4 py-2.5 bg-zinc-50 border-b border-zinc-200 flex items-center justify-between shrink-0">
582+
<div class="flex items-center gap-2">
583+
<span class="text-xs font-semibold text-zinc-500 uppercase tracking-wider">Source</span>
584+
<code class="font-mono text-[11px] text-zinc-400">embed.html</code>
585+
</div>
586+
<button class="copy-btn flex items-center gap-1.5 px-2 py-1 rounded text-[11px] font-semibold bg-white text-zinc-500 border border-zinc-200 hover:text-zinc-800 transition-colors" data-target="embed-src">
587+
<svg class="w-3 h-3" viewBox="0 0 16 16" fill="currentColor"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"/><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"/></svg>
588+
Copy
589+
</button>
590+
</div>
591+
<pre id="embed-src" class="flex-1 overflow-auto p-4 text-[11.5px] font-mono leading-relaxed bg-white text-zinc-700 whitespace-pre" style="height:580px">Loading…</pre>
592+
</div>
593+
594+
</div>
595+
596+
</div><!-- /page-embed -->
597+
559598
<!-- Footer -->
560599
<footer class="mt-6 text-xs text-zinc-400 pb-4 border-t border-zinc-200 pt-4">
561600
<a href="https://github.com/ihatexcel/iframe-flight" target="_blank" class="text-blue-600 hover:underline">github.com/ihatexcel/iframe-flight</a>
@@ -582,6 +621,7 @@ <h1 class="text-xl font-bold text-zinc-900 tracking-tight">✈ iframe-flight</h1
582621
});
583622
if (page === 'simple') initQsEmitter();
584623
if (page === 'chart') initChartEmitter();
624+
if (page === 'embed') initEmbed();
585625
}
586626
window.addEventListener('hashchange', route);
587627
route();
@@ -768,6 +808,18 @@ <h1 class="text-xl font-bold text-zinc-900 tracking-tight">✈ iframe-flight</h1
768808
q('btn-resume-alpha').addEventListener('click',()=>{ q('frame-alpha').contentWindow.postMessage({__iframeFlight:'resume'},'*'); q('btn-resume-alpha').disabled=true; appendLog('parent-log','▶ resume → child-alpha','info'); });
769809
q('btn-resume-beta').addEventListener('click',()=>{ q('frame-beta').contentWindow.postMessage({__iframeFlight:'resume'},'*'); q('btn-resume-beta').disabled=true; appendLog('parent-log','▶ resume → child-beta','info'); });
770810

811+
/* ══ EMBED PAGE — lazy init ══ */
812+
let embedInited = false;
813+
function initEmbed() {
814+
if (embedInited) return;
815+
embedInited = true;
816+
q('embed-frame').src = './embed.html';
817+
fetch('./embed.html')
818+
.then(r => r.text())
819+
.then(src => { q('embed-src').textContent = src; })
820+
.catch(() => { q('embed-src').textContent = '(could not load source)'; });
821+
}
822+
771823
/* ══ CHART PAGE — lazy init ══ */
772824
const CHART_PRODUCTS = ['Aurora','Beacon','Catalyst','Dynamo','Ember','Forge','Helios','Iris','Jetstream','Kronos','Lumina','Meridian','Nexus','Orbit','Prism'];
773825

0 commit comments

Comments
 (0)