talos/website/static/js/clipboard.js
Noel Georgi 6665e0f00c
docs: code block copying
Enable code blocks copying

Ref: https://aaronluna.dev/blog/add-copy-button-to-code-blocks-hugo-chroma/

Supersedes #5235

Signed-off-by: Noel Georgi <git@frezbo.dev>
2022-03-29 19:16:44 +05:30

63 lines
2.0 KiB
JavaScript

function createCopyButton(highlightDiv) {
const button = document.createElement("button");
button.className = "copy-code-button";
button.type = "button";
button.innerText = "Copy";
button.addEventListener("click", () => copyCodeToClipboard(button, highlightDiv));
addCopyButtonToDom(button, highlightDiv);
}
async function copyCodeToClipboard(button, highlightDiv) {
const codeToCopy = highlightDiv.querySelector(":last-child > code").innerText;
try {
result = await navigator.permissions.query({ name: "clipboard-write" });
if (result.state == "granted" || result.state == "prompt") {
await navigator.clipboard.writeText(codeToCopy);
} else {
copyCodeBlockExecCommand(codeToCopy, highlightDiv);
}
} catch (_) {
copyCodeBlockExecCommand(codeToCopy, highlightDiv);
}
finally {
codeWasCopied(button);
}
}
function copyCodeBlockExecCommand(codeToCopy, highlightDiv) {
const textArea = document.createElement("textArea");
textArea.contentEditable = 'true'
textArea.readOnly = 'false'
textArea.className = "copyable-text-area";
textArea.value = codeToCopy;
highlightDiv.insertBefore(textArea, highlightDiv.firstChild);
const range = document.createRange()
range.selectNodeContents(textArea)
const sel = window.getSelection()
sel.removeAllRanges()
sel.addRange(range)
textArea.setSelectionRange(0, 999999)
document.execCommand("copy");
highlightDiv.removeChild(textArea);
}
function codeWasCopied(button) {
button.blur();
button.innerText = "Copied!";
setTimeout(function() {
button.innerText = "Copy";
}, 2000);
}
function addCopyButtonToDom(button, highlightDiv) {
highlightDiv.insertBefore(button, highlightDiv.firstChild);
const wrapper = document.createElement("div");
wrapper.className = "highlight-wrapper";
highlightDiv.parentNode.insertBefore(wrapper, highlightDiv);
wrapper.appendChild(highlightDiv);
}
document.querySelectorAll(".highlight")
.forEach(highlightDiv => createCopyButton(highlightDiv));