Add copy button to copy code block contents (#345)
* add buttons to copy code block contents Adds a clickable "copy" link in the top-right corner of each code block. If available, uses the navigator.clipboard API. Falls back to selecting the text and calling document.execCommand('copy') to copy text. * hides copy button unless mouse is hovering over code block * change text of copy button when text is copied * add translation keys for copy button text `code_copy` and `code_copied` * To disable use `Params.disableCodeCopy: true` in site config
This commit is contained in:
parent
f1bc3471a6
commit
17c4da86b5
|
@ -41,5 +41,25 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
code {
|
code {
|
||||||
direction: ltr
|
direction: ltr;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.highlight {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.copy-code {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
top: 4px;
|
||||||
|
right: 4px;
|
||||||
|
color: rgba(255, 255, 255, 0.8);
|
||||||
|
background: rgba(78, 78, 78, 0.8);
|
||||||
|
border-radius: var(--radius);
|
||||||
|
padding: 0 5px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.highlight:hover .copy-code {
|
||||||
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,3 +17,9 @@
|
||||||
|
|
||||||
- id: home
|
- id: home
|
||||||
translation: "Home"
|
translation: "Home"
|
||||||
|
|
||||||
|
- id: code_copy
|
||||||
|
translation: "copy"
|
||||||
|
|
||||||
|
- id: code_copied
|
||||||
|
translation: "copied!"
|
||||||
|
|
|
@ -84,3 +84,43 @@
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
|
||||||
|
{{- if (not .Site.Params.disableCodeCopy) }}
|
||||||
|
<script>
|
||||||
|
document.querySelectorAll('pre > code').forEach((codeblock) => {
|
||||||
|
const container = codeblock.parentNode.parentNode;
|
||||||
|
|
||||||
|
const copybutton = document.createElement('button');
|
||||||
|
copybutton.classList.add('copy-code');
|
||||||
|
copybutton.innerText = '{{- i18n "code_copy" | default "copy" }}';
|
||||||
|
|
||||||
|
function copyingDone() {
|
||||||
|
copybutton.innerText = '{{- i18n "code_copied" | default "copied!" }}';
|
||||||
|
setTimeout(() => {
|
||||||
|
copybutton.innerText = '{{- i18n "code_copy" | default "copy" }}';
|
||||||
|
}, 2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
copybutton.addEventListener('click', (cb) => {
|
||||||
|
if ('clipboard' in navigator) {
|
||||||
|
navigator.clipboard.writeText(codeblock.textContent);
|
||||||
|
copyingDone();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const range = document.createRange();
|
||||||
|
range.selectNodeContents(codeblock);
|
||||||
|
const selection = window.getSelection();
|
||||||
|
selection.removeAllRanges();
|
||||||
|
selection.addRange(range);
|
||||||
|
try {
|
||||||
|
document.execCommand('copy');
|
||||||
|
copyingDone();
|
||||||
|
} catch (e) { };
|
||||||
|
selection.removeRange(range);
|
||||||
|
});
|
||||||
|
|
||||||
|
container.appendChild(copybutton);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{{- end }}
|
||||||
|
|
Loading…
Reference in New Issue