feat: use Hugo's code block render hook to implement code copy button

Now it can have i18n support
This commit is contained in:
Jimmy Cai 2022-06-12 11:31:32 +00:00 committed by GitHub
parent abf0c773aa
commit de08e29b00
3 changed files with 50 additions and 33 deletions

28
assets/ts/codeblock.ts Normal file
View file

@ -0,0 +1,28 @@
/**
* Copy button for code blocks
*/
export default () => {
const copyButtons = document.querySelectorAll('.codeblock-copy');
copyButtons.forEach(button => {
const codeblockID = button.getAttribute('data-id'),
copyText = button.textContent,
copiedText = button.getAttribute('data-copied-text');
if (!codeblockID) return;
button.addEventListener('click', (e) => {
e.preventDefault();
const codeblock = document.getElementById(codeblockID) as HTMLElement;
if (!codeblockID) return;
navigator.clipboard.writeText(codeblock.textContent)
.then(() => {
button.textContent = copiedText;
setTimeout(() => {
button.textContent = copyText;
}, 1000);
})
.catch(err => {
alert(err)
console.log('Something went wrong', err);
});
}, false);
});
}

View file

@ -6,7 +6,7 @@
* @link: https://github.com/CaiJimmy/hugo-theme-stack
*/
import StackGallery from "ts/gallery";
import { getColor } from 'ts/color';
import StackCodeBlock from "ts/codeblock";
import menu from 'ts/menu';
import createElement from 'ts/createElement';
import StackColorScheme from 'ts/colorScheme';
@ -27,39 +27,8 @@ let Stack = {
setupScrollspy();
}
/**
* Add copy button to code block
*/
const highlights = document.querySelectorAll('.article-content div.highlight');
const copyText = `Copy`,
copiedText = `Copied!`;
highlights.forEach(highlight => {
const copyButton = document.createElement('button');
copyButton.innerHTML = copyText;
copyButton.classList.add('copyCodeButton');
highlight.appendChild(copyButton);
const codeBlock = highlight.querySelector('code[data-lang]');
if (!codeBlock) return;
copyButton.addEventListener('click', () => {
navigator.clipboard.writeText(codeBlock.textContent)
.then(() => {
copyButton.textContent = copiedText;
setTimeout(() => {
copyButton.textContent = copyText;
}, 1000);
})
.catch(err => {
alert(err)
console.log('Something went wrong', err);
});
});
});
new StackColorScheme(document.getElementById('dark-mode-toggle'));
StackCodeBlock();
}
}

View file

@ -0,0 +1,20 @@
{{- $class := .Attributes.class | default "" -}}
{{- $lang := .Attributes.lang | default .Type -}}
<div class="codeblock">
<header>
<span class="codeblock-lang">{{ $lang }}</span>
<button
class="codeblock-copy"
data-id="codeblock-id-{{ .Ordinal }}"
data-copied-text="Copied!"
>
Copy
</button>
</header>
<code id="codeblock-id-{{ .Ordinal }}" style="display:none;">{{- .Inner -}}</code>
{{- if transform.CanHighlight $lang -}}
<div class="{{ $class }}">{{- highlight .Inner $lang -}}</div>
{{- else -}}
<pre><code class="{{ $class }}">{{- .Inner -}}</code></pre>
{{- end -}}
</div>