Add buttons to copy code snippets
This commit is contained in:
parent
30bacfa6af
commit
79924b4d95
|
@ -37,6 +37,9 @@
|
|||
{% if toc %}
|
||||
<script src="{{'/assets/js/details-utils.js'}}" defer></script>
|
||||
{% endif %}
|
||||
{% if hasCodeBlock %}
|
||||
<script src="/assets/js/copycode.js" defer></script>
|
||||
{% endif %}
|
||||
{% if hasTooltips %}
|
||||
<script src="/assets/js/tooltips.js" defer></script>
|
||||
{% endif %}
|
||||
|
|
|
@ -5,6 +5,7 @@ updated: 2024-12-03T23:51:27+0800
|
|||
desc: "How I implement accessible footnotes, at least to the best of my ability. Written for 32-Bit Cafe's Community Code Jam #5."
|
||||
categories: ["32-bit cafe", "accessibility", "html", "css", "eleventy", "markdown-it"]
|
||||
toc: true
|
||||
hasCodeBlock: true
|
||||
---
|
||||
|
||||
[](https://32bit.cafe/~xandra/events/codejam5/){.inline-img}
|
||||
|
|
|
@ -103,6 +103,20 @@
|
|||
|
||||
a.link-btn[href^="http"]:not([href*="leilukin.com"]) { padding-right: calc(var(--btn-right-padding) + var(--sz-external-link)); }
|
||||
|
||||
/* Button to copy code snippets */
|
||||
.cc-btn {
|
||||
font-size: 0.8em;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.2em;
|
||||
margin-left: auto;
|
||||
margin-right: 0;
|
||||
border: 0.15em solid var(--clr-code-border);
|
||||
border-radius: 0.2em;
|
||||
background: var(--clr-link-btn-bg);
|
||||
color: var(--clr-link-btn-txt);
|
||||
}
|
||||
|
||||
/* Content Disclosure */
|
||||
* + .content-disclosure { margin-top: var(--sz-paragraph-margin); }
|
||||
.content-disclosure__summary { font-weight: 700; }
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
function createCopyBtn(blockIndex) {
|
||||
return `<div class="cc-wrapper d-none d-sm-block">
|
||||
<button class="cc-btn btn-muted shadow" title="Copy code" data-target="${blockIndex}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="icon"><path stroke="none"d="M0 0h24v24H0z"fill="none"/><path d="M9 5h-2a2 2 0 0 0 -2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-12a2 2 0 0 0 -2 -2h-2"/><path d="M9 3m0 2a2 2 0 0 1 2 -2h2a2 2 0 0 1 2 2v0a2 2 0 0 1 -2 2h-2a2 2 0 0 1 -2 -2z"/></svg>
|
||||
Copy Code
|
||||
</button>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
async function copyCode(block) {
|
||||
const code = document.querySelector(`[data-block-id="${block}"]`);
|
||||
const doCopy = async() => await navigator.clipboard.writeText(code?.innerText ?? '');
|
||||
|
||||
if (!navigator.userAgent.includes('Firefox')) {
|
||||
const result = await navigator.permissions.query({ name: 'clipboard-write' });
|
||||
|
||||
if (result.state === 'granted' || result.state === 'prompt') {
|
||||
doCopy();
|
||||
}
|
||||
} else {
|
||||
doCopy();
|
||||
}
|
||||
}
|
||||
|
||||
async function handleCopyBtnClick(event) {
|
||||
const btn = event?.target;
|
||||
const btnTarget = btn?.getAttribute('data-target');
|
||||
|
||||
if (btn && btnTarget) {
|
||||
const originalText = btn.innerHTML;
|
||||
|
||||
await copyCode(btnTarget);
|
||||
|
||||
btn.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="icon"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M9 5h-2a2 2 0 0 0 -2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-12a2 2 0 0 0 -2 -2h-2" /><path d="M9 3m0 2a2 2 0 0 1 2 -2h2a2 2 0 0 1 2 2v0a2 2 0 0 1 -2 2h-2a2 2 0 0 1 -2 -2z" /><path d="M9 14l2 2l4 -4" /></svg> Copied!';
|
||||
|
||||
setTimeout(() => {
|
||||
btn.innerHTML = originalText;
|
||||
}, 1500);
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const allCodeBlocks = Array.from(document.querySelectorAll('pre[class^="language-"]'));
|
||||
|
||||
allCodeBlocks.forEach((b, i) => {
|
||||
const code = b.childNodes[0];
|
||||
const codeBlockIndex = `cb-${i}`;
|
||||
|
||||
b.insertAdjacentHTML('afterend', createCopyBtn(codeBlockIndex));
|
||||
code.setAttribute('data-block-id', codeBlockIndex);
|
||||
})
|
||||
|
||||
const allCopyBtns = Array.from(document.querySelectorAll('.cc-btn'));
|
||||
|
||||
allCopyBtns.forEach((btn) => {
|
||||
btn.addEventListener('click', handleCopyBtnClick);
|
||||
})
|
||||
})
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
date: 2025-02-17T18:10:52+0800
|
||||
---
|
||||
|
||||
* Add buttons to copy code snippets to pages with code blocks.
|
|
@ -1,3 +1,4 @@
|
|||
export default {
|
||||
tags: ["code snippets"]
|
||||
tags: ["code snippets"],
|
||||
hasCodeBlock: true
|
||||
}
|
|
@ -5,6 +5,7 @@ updated: 2024-05-10
|
|||
desc: "Juhani is a canon lesbian character and she has always been intended as such by the developers of Knights of the Old Republic. Here I am presenting evidence from the game files to prove it."
|
||||
tags: kotor 1 articles
|
||||
categories: ["star wars kotor"]
|
||||
hasCodeBlock: true
|
||||
---
|
||||
|
||||
(Note: This article was originally published on Tumblr)
|
||||
|
|
Loading…
Reference in New Issue