const successIcon = ``;
const errorIcon = ``;
const copyIcon = `
`;
// Function to change icons after copying
const changeIcon = (button, isSuccess) => {
button.innerHTML = isSuccess ? successIcon : errorIcon;
setTimeout(() => {
button.innerHTML = copyIcon; // Reset to copy icon
}, 2000);
};
// Function to get code text from tables, skipping line numbers
const getCodeFromTable = (codeBlock) => {
return [...codeBlock.querySelectorAll("tr")]
.map((row) => row.querySelector("td:last-child")?.innerText ?? "")
.join("");
};
// Function to get code text from non-table blocks
const getNonTableCode = (codeBlock) => {
return codeBlock.textContent.trim();
};
document.addEventListener("DOMContentLoaded", function () {
// Select all `pre` elements containing `code`
document.querySelectorAll("pre code").forEach((codeBlock) => {
const pre = codeBlock.parentNode;
pre.style.position = "relative"; // Ensure parent `pre` can contain absolute elements
// Create and append the copy button
const copyBtn = document.createElement("button");
copyBtn.className = "clipboard-button";
copyBtn.innerHTML = copyIcon;
copyBtn.setAttribute("aria-label", "Copy code to clipboard");
pre.appendChild(copyBtn);
// Create and append the language label
const langClass = codeBlock.className.match(/language-(\w+)/);
const lang = langClass ? langClass[1].toUpperCase() : "TEXT";
const label = document.createElement("span");
label.className = "code-label label-" + lang.toLowerCase();
label.textContent = lang;
pre.appendChild(label);
// Attach event listener to copy button
copyBtn.addEventListener("click", async () => {
const codeToCopy = codeBlock.textContent.trim(); // Get the code content
try {
await navigator.clipboard.writeText(codeToCopy);
changeIcon(copyBtn, true); // Show success icon
} catch (error) {
console.error("Failed to copy text: ", error);
changeIcon(copyBtn, false); // Show error icon
}
});
let ticking = false;
pre.addEventListener("scroll", () => {
if (!ticking) {
window.requestAnimationFrame(() => {
copyBtn.style.right = `-${pre.scrollLeft}px`; // Ensure button stays on the right
label.style.left = `${pre.scrollLeft}px`; // Ensure label stays on the left
ticking = false;
});
ticking = true;
}
});
});
});