|
// retoor <retoor@molodetz.nl>
|
|
|
|
export class CodeBlock {
|
|
static highlight(code) {
|
|
if (typeof hljs === "undefined" || !code) return;
|
|
code.removeAttribute("data-highlighted");
|
|
code.classList.remove("hljs");
|
|
try {
|
|
hljs.highlightElement(code);
|
|
} catch {
|
|
// leave plain text on failure
|
|
}
|
|
}
|
|
|
|
static lineNumbers(pre, code) {
|
|
pre.classList.add("code-pre", "has-line-numbers");
|
|
let gutter = pre.querySelector(":scope > .code-gutter");
|
|
if (!gutter) {
|
|
gutter = document.createElement("span");
|
|
gutter.className = "code-gutter";
|
|
gutter.setAttribute("aria-hidden", "true");
|
|
pre.insertBefore(gutter, code);
|
|
}
|
|
const text = code.textContent.replace(/\n+$/, "");
|
|
const count = text.length ? text.split("\n").length : 1;
|
|
gutter.textContent = Array.from({ length: count }, (_, i) => i + 1).join("\n");
|
|
}
|
|
|
|
static copyButton(pre, code) {
|
|
if (pre.querySelector(":scope > .code-copy-btn")) return;
|
|
const btn = document.createElement("button");
|
|
btn.type = "button";
|
|
btn.className = "code-copy-btn";
|
|
btn.textContent = "Copy";
|
|
btn.addEventListener("click", async () => {
|
|
try {
|
|
await navigator.clipboard.writeText(code.textContent);
|
|
btn.textContent = "Copied";
|
|
} catch {
|
|
btn.textContent = "Failed";
|
|
}
|
|
setTimeout(() => { btn.textContent = "Copy"; }, 1500);
|
|
});
|
|
pre.appendChild(btn);
|
|
}
|
|
|
|
static enhance(pre, { highlight = true, lineNumbers = true } = {}) {
|
|
if (!pre) return;
|
|
const code = pre.querySelector("code");
|
|
if (!code) return;
|
|
if (highlight && !code.classList.contains("hljs")) this.highlight(code);
|
|
pre.classList.add("code-has-copy");
|
|
if (lineNumbers) this.lineNumbers(pre, code);
|
|
this.copyButton(pre, code);
|
|
}
|
|
|
|
static refresh(pre) {
|
|
if (!pre) return;
|
|
const code = pre.querySelector("code");
|
|
if (!code) return;
|
|
this.highlight(code);
|
|
pre.classList.add("code-has-copy");
|
|
this.lineNumbers(pre, code);
|
|
this.copyButton(pre, code);
|
|
}
|
|
}
|
|
|
|
window.CodeBlock = CodeBlock;
|