diff --git a/assets/js/code.js b/assets/js/code.js index f2efe534..173d8b6e 100644 --- a/assets/js/code.js +++ b/assets/js/code.js @@ -1,10 +1,6 @@ var scriptBundle = document.getElementById("script-bundle"); -var copyText = - scriptBundle && scriptBundle.getAttribute("data-copy") ? scriptBundle.getAttribute("data-copy") : "Copy"; -var copiedText = - scriptBundle && scriptBundle.getAttribute("data-copied") - ? scriptBundle.getAttribute("data-copied") - : "Copied"; +var copyText = scriptBundle?.getAttribute("data-copy") || "Copy"; +var copiedText = scriptBundle?.getAttribute("data-copied") || "Copied"; function createCopyButton(highlightDiv) { const button = document.createElement("button"); @@ -13,26 +9,53 @@ function createCopyButton(highlightDiv) { button.ariaLabel = copyText; button.innerText = copyText; button.addEventListener("click", () => copyCodeToClipboard(button, highlightDiv)); - 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); } async function copyCodeToClipboard(button, highlightDiv) { - const codeToCopy = getCleanCodeText(highlightDiv); + const codeToCopy = getCodeText(highlightDiv); + + function fallback(codeToCopy, highlightDiv) { + const textArea = document.createElement("textArea"); + textArea.contentEditable = "true"; + textArea.readOnly = "false"; + textArea.className = "copy-textarea"; + 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); + } + 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); + fallback(codeToCopy, highlightDiv); } } catch (_) { - copyCodeBlockExecCommand(codeToCopy, highlightDiv); + fallback(codeToCopy, highlightDiv); } finally { - codeWasCopied(button); + button.blur(); + button.innerText = copiedText; + setTimeout(function () { + button.innerText = copyText; + }, 2000); } } -function getCleanCodeText(highlightDiv) { +function getCodeText(highlightDiv) { const codeElement = highlightDiv.querySelector("code"); if (!codeElement) return ""; @@ -51,39 +74,6 @@ function getCleanCodeText(highlightDiv) { return codeElement.textContent.trim(); } -function copyCodeBlockExecCommand(codeToCopy, highlightDiv) { - const textArea = document.createElement("textArea"); - textArea.contentEditable = "true"; - textArea.readOnly = "false"; - textArea.className = "copy-textarea"; - 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 = copiedText; - setTimeout(function () { - button.innerText = copyText; - }, 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); -} - window.addEventListener("DOMContentLoaded", (event) => { document.querySelectorAll(".highlight").forEach((highlightDiv) => createCopyButton(highlightDiv)); });