Skip to content

Commit 76268fa

Browse files
authored
Add copy button for code blocks (#418)
1 parent af058a5 commit 76268fa

3 files changed

Lines changed: 79 additions & 0 deletions

File tree

assets/js/copy-code-blocks.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// copy-code-blocks.js
2+
3+
// This file implements a button attached to code blocks which copies
4+
// the code to the clipboard.
5+
6+
// This selector should match the PRE elements, each of which may
7+
// itself contain the text to be copied, or may contain a CODE element
8+
// which contains the text to be copied.
9+
const pre_selector = "div.highlight pre";
10+
11+
document.querySelectorAll(pre_selector).forEach(add_button_to);
12+
13+
function add_button_to(element) {
14+
div = document.createElement("div");
15+
button = document.createElement("button");
16+
div.classList.add("copy-button");
17+
button.addEventListener("click", copy_content_of);
18+
div.append(button);
19+
element.prepend(div);
20+
}
21+
22+
function copy_content_of(event) {
23+
content = this.parentElement.parentElement.textContent + "\n";
24+
navigator.clipboard.writeText(content).then(() => update_button(this));
25+
}
26+
27+
function update_button(button, clicked_class = "clicked", timeout_ms = 2000) {
28+
button.classList.add(clicked_class);
29+
setTimeout(() => button.classList.remove(clicked_class), timeout_ms);
30+
}
31+
32+
// copy-code-blocks.js ends.

assets/theme-css/code.scss

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Rules for code blocks, including the copy button.
2+
3+
// Selector from "pst/content/_code.scss".
4+
div[class*="highlight-"],
5+
div.highlight,
6+
div.literal-block-wrapper {
7+
// Copy-to-clipboard button.
8+
& .copy-button {
9+
bottom: 10px;
10+
float: right;
11+
font-size: 0.875em;
12+
left: 10px;
13+
position: relative;
14+
visibility: hidden;
15+
z-index: 1;
16+
}
17+
&:hover .copy-button {
18+
visibility: visible;
19+
}
20+
& .chroma .copy-button button {
21+
// Fix alignment that the .chroma rules affect.
22+
padding: 0.5rem;
23+
}
24+
25+
& button {
26+
background: var(--pst-color-surface);
27+
border: none;
28+
color: var(--pst-color-text-base);
29+
30+
// These classes are changed upon click by the script.
31+
&:not(.clicked):hover::before {
32+
content: "Copy ";
33+
}
34+
&.clicked::before {
35+
content: "Copied ";
36+
}
37+
38+
&::after {
39+
// The Font Awesome copy icon.
40+
content: var(--fa-copy);
41+
font: var(--fa-font-regular);
42+
}
43+
}
44+
}

assets/theme-css/vars.css

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,7 @@
1414
--colorYellow: rgb(255, 197, 83);
1515

1616
--spht-footer-height: 6em;
17+
18+
/* Font Awesome icon variables. */
19+
--fa-copy: "\f0c5"; /* fa-solid fa-copy */
1720
}

0 commit comments

Comments
 (0)