Merge pull request #2426 from ZhenShuo2021/fix/code-copy

🐛 Fix(code.js): filter line number on code copy
This commit is contained in:
Nuno C.
2025-09-15 23:03:55 +01:00
committed by GitHub
+38 -29
View File
@@ -1,10 +1,6 @@
var scriptBundle = document.getElementById("script-bundle"); var scriptBundle = document.getElementById("script-bundle");
var copyText = var copyText = scriptBundle?.getAttribute("data-copy") || "Copy";
scriptBundle && scriptBundle.getAttribute("data-copy") ? scriptBundle.getAttribute("data-copy") : "Copy"; var copiedText = scriptBundle?.getAttribute("data-copied") || "Copied";
var copiedText =
scriptBundle && scriptBundle.getAttribute("data-copied")
? scriptBundle.getAttribute("data-copied")
: "Copied";
function createCopyButton(highlightDiv) { function createCopyButton(highlightDiv) {
const button = document.createElement("button"); const button = document.createElement("button");
@@ -13,26 +9,18 @@ function createCopyButton(highlightDiv) {
button.ariaLabel = copyText; button.ariaLabel = copyText;
button.innerText = copyText; button.innerText = copyText;
button.addEventListener("click", () => copyCodeToClipboard(button, highlightDiv)); 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) { async function copyCodeToClipboard(button, highlightDiv) {
const codeToCopy = highlightDiv.querySelector(":last-child").innerText; const codeToCopy = getCodeText(highlightDiv);
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) { function fallback(codeToCopy, highlightDiv) {
const textArea = document.createElement("textArea"); const textArea = document.createElement("textArea");
textArea.contentEditable = "true"; textArea.contentEditable = "true";
textArea.readOnly = "false"; textArea.readOnly = "false";
@@ -49,20 +37,41 @@ function copyCodeBlockExecCommand(codeToCopy, highlightDiv) {
highlightDiv.removeChild(textArea); highlightDiv.removeChild(textArea);
} }
function codeWasCopied(button) { 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.blur();
button.innerText = copiedText; button.innerText = copiedText;
setTimeout(function () { setTimeout(function () {
button.innerText = copyText; button.innerText = copyText;
}, 2000); }, 2000);
} }
}
function addCopyButtonToDom(button, highlightDiv) { function getCodeText(highlightDiv) {
highlightDiv.insertBefore(button, highlightDiv.firstChild); const codeBlock = highlightDiv.querySelector("code");
const wrapper = document.createElement("div"); const inlineLines = codeBlock?.querySelectorAll(".cl"); // linenos=inline
wrapper.className = "highlight-wrapper"; const tableCodeCell = highlightDiv?.querySelector(".lntable .lntd:last-child code"); // linenos=table
highlightDiv.parentNode.insertBefore(wrapper, highlightDiv);
wrapper.appendChild(highlightDiv); 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) => { window.addEventListener("DOMContentLoaded", (event) => {