diff --git a/assets/js/code.js b/assets/js/code.js index 8639ad8d..2cc852ec 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,51 +9,7 @@ function createCopyButton(highlightDiv) { button.ariaLabel = copyText; button.innerText = copyText; button.addEventListener("click", () => copyCodeToClipboard(button, highlightDiv)); - addCopyButtonToDom(button, highlightDiv); -} -async function copyCodeToClipboard(button, highlightDiv) { - const codeToCopy = highlightDiv.querySelector(":last-child").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 = "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"; @@ -65,6 +17,63 @@ function addCopyButtonToDom(button, highlightDiv) { wrapper.appendChild(highlightDiv); } +async function copyCodeToClipboard(button, 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 { + fallback(codeToCopy, highlightDiv); + } + } catch (_) { + fallback(codeToCopy, highlightDiv); + } finally { + button.blur(); + button.innerText = copiedText; + setTimeout(function () { + button.innerText = copyText; + }, 2000); + } +} + +function getCodeText(highlightDiv) { + const codeBlock = highlightDiv.querySelector("code"); + const inlineLines = codeBlock?.querySelectorAll(".cl"); // linenos=inline + const tableCodeCell = highlightDiv?.querySelector(".lntable .lntd:last-child code"); // linenos=table + + if (!codeBlock) return ""; + + if (inlineLines.length > 0) { + const cleanedLines = Array.from(inlineLines).map((line) => line.textContent.replace(/\n$/, "")); + return cleanedLines.join("\n"); + } + + if (tableCodeCell) { + return tableCodeCell.textContent.trim(); + } + + return codeBlock.textContent.trim(); +} + window.addEventListener("DOMContentLoaded", (event) => { document.querySelectorAll(".highlight").forEach((highlightDiv) => createCopyButton(highlightDiv)); });