Na primeira vez em que tentei configurar um botão Copy
para as caixas de código, deixei uma nota no GitHub do tema Zdoc.
Há dias um outro utilizador do Zdoc publicou a solução que funcionou para ele, e com esse estímulo, tentei de novo.
Infelizmente, já devo ter manipulado de mais o DOM da minha versão do tema (manter-me compatível com o upstream, infelizmente, não vai dar para já) para poder utilizar directamente o código dele, mas tentei mexer mais um pouco no código que tinha tentado utilizar anteriormente, que era baseado nesta solução proposta por Tom Spencer
Com as minhas alterações, ficou assim:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
// insert just before the </script> tag
// tomspencer, https://www.tomspencer.dev/blog/2018/09/14/adding-click-to-copy-buttons-to-a-hugo-powered-blog/
(function() {
'use strict';
if(!document.queryCommandSupported('copy')) {
return;
}
function flashCopyMessage(el, msg) {
el.textContent = msg;
setTimeout(function() {
el.textContent = "COPY";
}, 1000);
}
function selectText(node) {
var selection = window.getSelection();
var range = document.createRange();
range.selectNodeContents(node);
selection.removeAllRanges();
selection.addRange(range);
return selection;
}
function addCopyButton(containerEl) {
var copyBtn = document.createElement("button");
copyBtn.className = "highlight-copy-btn";
copyBtn.textContent = "COPY";
var codeEl = containerEl.firstElementChild;
copyBtn.addEventListener('click', function() {
try {
var selection = selectText(codeEl);
document.execCommand('copy');
selection.removeAllRanges();
flashCopyMessage(copyBtn, 'Copied!')
} catch(e) {
console && console.log(e);
flashCopyMessage(copyBtn, 'Failed :\'(')
}
});
containerEl.appendChild(copyBtn);
}
// Add copy button to code blocks
var highlightBlocks = document.getElementsByClassName('highlight');
for (var i = 0; i < highlightBlocks.length; i++) {
addCopyButton(highlightBlocks[i]);
}
})();
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
.highlight-copy-btn {
position: relative;
bottom: 22px;
right: 0px;
border: 0;
border-radius: 4px;
padding: 1px;
font-size: 0.6em;
line-height: 1.0;
opacity: 0.6;
min-width: 65px;
text-align: center;
letter-spacing: 2px;
@include themify($codeblock) {
color: themed('content-pre-color');
background: themed('content-pre-background-color');
border: 1.25px solid themed('border-line-color');
}
border-top-left-radius: 0;
border-top-right-radius: 4px;
border-bottom-right-radius: 0;
border-bottom-left-radius: 4px;
white-space: nowrap;
padding: 4px 4px 5px 4px;
margin: 0 0 0 1px;
cursor: pointer;
opacity: 0.6;
}
.highlight-copy-btn:hover {
@include themify($themes) {
color: themed('link');
background-color: themed('body-background-color');
}
}
|
Funciona mais ou menos, mas só nos blocos de código para os quais foi detectada uma sintaxe (ou seja, em que o div class
é highlight
e o chroma
foi activado). Para os outros, como os blocos de código nativos do MarkDown, não, e há ocasiões em que não posso ou não quero activar o chroma. Que fazer nesse caso?
O código do Preston Rodriguez, que agradeço, não funciona com as alterações que já fiz ao tema e que não consigo desfazer nem perceber onde estão a falhar (já disse que não pesco quase nada de JavaScript?)
Tentei repetir, sem sucesso, o código do Tom Spencer em layouts/partials/head/scripts.html
, mas usando como selector
var codeBlocks = document.querySelectorAll('pre > code');
codeBlocks.forEach(function(plainBlock) {
addCopyButton(plainBlock);
}
(um perfeito exemplo da questão - neste momento o botão COPY não aparece aqui, mas se conseguir resolver isto, vai passar a aparecer)