Spaces:
Running
Running
File size: 3,404 Bytes
5ea40ce 5da533e 5ea40ce 5da533e 5ea40ce 5da533e 5ea40ce 5da533e 5ea40ce | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | // code-snippet.js, wires up every .code-snippet on the page.
//
// Each snippet has tabs (Endpoint / Local) and a copy button. We listen on
// click for tab switching and copy-to-clipboard.
//
// Markup contract:
// <details class="code-snippet">
// <summary>Run this from code</summary>
// <div class="code-snippet__body">
// <div class="code-snippet__tabs">
// <button class="code-snippet__tab active" data-tab="endpoint">…</button>
// <button class="code-snippet__tab" data-tab="local">…</button>
// </div>
// <button class="code-snippet__copy" type="button">Copy</button>
// <div class="code-snippet__panel active" data-tab="endpoint"><pre><code>…</code></pre></div>
// <div class="code-snippet__panel" data-tab="local"><pre><code>…</code></pre></div>
// </div>
// </details>
(function () {
function activate(snippet, name) {
snippet.querySelectorAll(".code-snippet__tab").forEach(t => {
t.classList.toggle("active", t.dataset.tab === name);
});
snippet.querySelectorAll(".code-snippet__panel").forEach(p => {
p.classList.toggle("active", p.dataset.tab === name);
});
}
// Run every <code> block through highlight.js. Every snippet in the demo
// is Python, so we hard-tag the language rather than rely on autodetect
// (which can mis-call short snippets). hljs is loaded via CDN with the
// same `defer` attribute as this script, but in case CSP / network
// blocks it we no-op gracefully and the snippets stay plain text.
function highlight(snippet) {
if (!window.hljs) return;
snippet.querySelectorAll(".code-snippet__panel code").forEach(code => {
if (code.dataset.highlighted) return;
code.classList.add("language-python");
try { window.hljs.highlightElement(code); } catch (e) { /* ignore */ }
code.dataset.highlighted = "1";
});
}
function wire(snippet) {
snippet.querySelectorAll(".code-snippet__tab").forEach(tab => {
tab.addEventListener("click", () => activate(snippet, tab.dataset.tab));
});
// Lift the copy button into the tabs strip if the markup still has it
// as a sibling. Lets the strip's flex layout vertically centre it
// against the tab pills instead of fighting absolute `top` pixels.
const tabsRow = snippet.querySelector(".code-snippet__tabs");
const copyBtn = snippet.querySelector(".code-snippet__copy");
if (tabsRow && copyBtn && copyBtn.parentNode !== tabsRow) {
tabsRow.appendChild(copyBtn);
}
if (copyBtn) {
copyBtn.addEventListener("click", async () => {
const panel = snippet.querySelector(".code-snippet__panel.active");
if (!panel) return;
const code = panel.querySelector("pre").textContent;
try {
await navigator.clipboard.writeText(code);
copyBtn.textContent = "Copied";
copyBtn.classList.add("copied");
setTimeout(() => {
copyBtn.textContent = "Copy";
copyBtn.classList.remove("copied");
}, 1500);
} catch (e) { /* clipboard blocked; fail quietly */ }
});
}
highlight(snippet);
}
function init() {
document.querySelectorAll(".code-snippet").forEach(wire);
}
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", init);
} else {
init();
}
})();
|