the home site for me: also iteration 3 or 4 of my site
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 83 lines 2.6 kB view raw
1// Based on https://www.roboleary.net/2022/01/13/copy-code-to-clipboard-blog.html 2 3function initCopyButtons() { 4 const blocks = document.querySelectorAll("pre.z-code"); 5 6 for (const block of blocks) { 7 // Code block header title 8 const title = document.createElement("span"); 9 title.style.color = "var(--accent-text)"; 10 const lang = block.querySelector("code[data-lang]")?.getAttribute("data-lang") ?? ""; 11 const comment = 12 block.previousElementSibling && 13 (block.previousElementSibling.tagName === "blockquote" || 14 block.previousElementSibling.nodeName === "BLOCKQUOTE") 15 ? block.previousElementSibling 16 : null; 17 if (comment) block.previousElementSibling.remove(); 18 title.innerHTML = 19 lang + (comment ? ` (${comment.textContent.trim()})` : ""); 20 21 // Copy button icon 22 const icon = document.createElement("i"); 23 icon.classList.add("icon"); 24 25 // Copy button 26 const button = document.createElement("button"); 27 const copyCodeText = "Copy code"; 28 button.setAttribute("title", copyCodeText); 29 button.appendChild(icon); 30 31 // Code block header 32 const header = document.createElement("div"); 33 header.classList.add("header"); 34 header.appendChild(title); 35 header.appendChild(button); 36 37 // Container that holds header and the code block itself 38 const container = document.createElement("div"); 39 container.classList.add("pre-container"); 40 container.appendChild(header); 41 42 // Move code block into the container 43 block.parentNode.insertBefore(container, block); 44 container.appendChild(block); 45 46 button.addEventListener("click", async () => { 47 await copyCode(block, header, button); 48 }); 49 } 50 51 async function copyCode(block, header, button) { 52 const code = block.querySelector("code"); 53 const text = code.innerText; 54 55 // Only try to copy if clipboard API is available 56 if (navigator.clipboard) { 57 try { 58 await navigator.clipboard.writeText(text); 59 button.blur(); 60 header.classList.add("active"); 61 button.setAttribute("disabled", true); 62 63 header.addEventListener( 64 "animationend", 65 () => { 66 header.classList.remove("active"); 67 button.removeAttribute("disabled"); 68 }, 69 { once: true }, 70 ); 71 } catch (err) { 72 console.error("Failed to copy:", err); 73 } 74 } 75 } 76} 77 78// Since the script has defer attribute, the DOM is already loaded when this runs 79if (document.readyState === 'loading') { 80 document.addEventListener('DOMContentLoaded', initCopyButtons); 81} else { 82 initCopyButtons(); 83}