feat: added "copy to clipboard" to code blocks

This commit is contained in:
geoffreygarrett 2022-06-30 15:41:04 +02:00
parent 635974c6fa
commit 8502be88b9
3 changed files with 26 additions and 20 deletions

View File

@ -5,17 +5,23 @@ const svgCheck =
const addCopyButtons = (clipboard) => { const addCopyButtons = (clipboard) => {
// 1. Look for pre > code elements in the DOM var els = document.getElementsByClassName("highlight");
document.querySelectorAll("pre > code").forEach((codeBlock) => { // for each highlight
// if buttom exists, skip for (var i = 0; i < els.length; i++) {
if (codeBlock.parentElement.querySelector(".clipboard-button")) return; if (els[i].getElementsByClassName("clipboard-button").length) continue;
// 2. Create a button that will trigger a copy operation
// find pre > code inside els[i]
let codeBlocks = els[i].getElementsByTagName("code");
// line numbers are inside first code block
let lastCodeBlock = codeBlocks[codeBlocks.length - 1];
const button = document.createElement("button"); const button = document.createElement("button");
button.className = "clipboard-button"; button.className = "clipboard-button";
button.type = "button"; button.type = "button";
button.innerHTML = svgCopy; button.innerHTML = svgCopy;
// remove every second newline from lastCodeBlock.innerText
button.addEventListener("click", () => { button.addEventListener("click", () => {
clipboard.writeText(codeBlock.innerText).then( clipboard.writeText(lastCodeBlock.innerText.replace(/\n\n/g, "\n")).then(
() => { () => {
button.blur(); button.blur();
button.innerHTML = svgCheck; button.innerHTML = svgCheck;
@ -24,12 +30,12 @@ const addCopyButtons = (clipboard) => {
(error) => (button.innerHTML = "Error") (error) => (button.innerHTML = "Error")
); );
}); });
// 3. Append the button directly before the pre tag // find chroma inside els[i]
const pre = codeBlock.parentNode; let chroma = els[i].getElementsByClassName("chroma")[0];
pre.parentNode.insertBefore(button, pre); els[i].insertBefore(button, chroma);
}); console.log(els[i].lastChild)
}; }
}
function initClipboard() { function initClipboard() {
if (navigator && navigator.clipboard) { if (navigator && navigator.clipboard) {

View File

@ -3,26 +3,26 @@
display: flex; display: flex;
float: right; float: right;
right: 0; right: 0;
padding: 0.7em; padding: 0.69em;
margin: 0.5em; margin: 0.5em;
color: var(--lightgray); color: var(--outlinegray);
border-color: var(--dark); border-color: var(--dark);
background-color: var(--lightgray); background-color: var(--lightgray);
filter: brightness(1.5); filter: contrast(1.1);
border: 1px solid; border: 2px solid;
border-radius: 6px; border-radius: 6px;
font-size: 0.8em; font-size: 0.8em;
z-index: 1; z-index: 1;
opacity: 0; opacity: 0;
transition: 0.1s; transition: 0.12s;
} }
.clipboard-button > svg { .clipboard-button > svg {
fill: var(--dark); fill: var(--light);
filter: contrast(0.3);
} }
.clipboard-button:hover { .clipboard-button:hover {
cursor: pointer; cursor: pointer;
border-color: var(--primary); border-color: var(--primary);
background-color: var(--dark);
} }
.clipboard-button:hover > svg { .clipboard-button:hover > svg {
fill: var(--primary); fill: var(--primary);

View File

@ -5,7 +5,7 @@ enableLinkPreview: true
enableLatex: true enableLatex: true
enableCodeBlockTitle: true enableCodeBlockTitle: true
enableClipboard: true enableClipboard: true
enableSPA: false enableSPA: true
enableFooter: true enableFooter: true
enableContextualBacklinks: true enableContextualBacklinks: true
enableRecentNotes: false enableRecentNotes: false