Skip to content

Commit 1b56477

Browse files
authored
resolves #13 add copy to clipboard button to source blocks (PR #14)
1 parent 1fe0909 commit 1b56477

File tree

5 files changed

+140
-13
lines changed

5 files changed

+140
-13
lines changed

src/css/doc.css

Lines changed: 72 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -638,26 +638,88 @@
638638
padding: 0.75rem;
639639
}
640640

641-
/* NOTE assume pre.highlight contains code[data-lang] */
642641
.doc pre.highlight {
643642
position: relative;
644643
}
645644

646-
.doc .listingblock code[data-lang]::before {
647-
content: attr(data-lang);
648-
display: none;
645+
.doc .language-console .hljs-meta {
646+
user-select: none;
647+
}
648+
649+
.doc .code-toolbox {
650+
display: flex;
651+
visibility: hidden;
652+
position: absolute;
653+
top: 0.25rem;
654+
right: 0.5rem;
649655
color: var(--pre-annotation-font-color);
650656
font-size: calc(13.5 / var(--rem-base) * 1rem);
651-
letter-spacing: 0.05em;
652657
line-height: 1;
658+
}
659+
660+
.doc .listingblock:hover .code-toolbox {
661+
visibility: visible;
662+
}
663+
664+
.doc .code-toolbox .code-lang {
653665
text-transform: uppercase;
666+
}
667+
668+
.doc .code-toolbox > :not(:last-child)::after {
669+
content: " | ";
670+
}
671+
672+
.doc .code-toolbox .copy-button {
673+
display: flex;
674+
flex-direction: column;
675+
align-items: center;
676+
background: transparent;
677+
border: none;
678+
color: inherit;
679+
outline: none;
680+
padding: 0;
681+
font-size: inherit;
682+
line-height: inherit;
683+
width: 1em;
684+
height: 1em;
685+
}
686+
687+
.code-toolbox .copy-button svg {
688+
flex: 0 0 auto;
689+
width: inherit;
690+
height: inherit;
691+
}
692+
693+
.code-toolbox .copy-toast {
694+
position: relative;
695+
display: inline-flex;
696+
justify-content: center;
697+
margin-top: 1em;
698+
background-color: var(--doc-font-color);
699+
border-radius: 0.25em;
700+
padding: 0.5em;
701+
color: #fff;
702+
font-family: var(--body-font-family);
703+
cursor: auto;
704+
opacity: 0;
705+
transition: opacity 0.5s ease 0.75s;
706+
}
707+
708+
.code-toolbox .copy-toast::after {
709+
content: "";
654710
position: absolute;
655-
top: 0.25rem;
656-
right: 0.25rem;
711+
top: 0;
712+
width: 1em;
713+
height: 1em;
714+
border: 0.55em solid transparent;
715+
border-left-color: var(--doc-font-color);
716+
transform: rotate(-90deg) translateX(50%) translateY(50%);
717+
transform-origin: left;
657718
}
658719

659-
.doc .listingblock:hover code[data-lang]::before {
660-
display: block;
720+
.code-toolbox .copy-button.clicked .copy-toast {
721+
opacity: 1;
722+
transition: none;
661723
}
662724

663725
.doc .dlist dt {
@@ -691,10 +753,10 @@
691753
font-family: var(--body-font-family);
692754
font-size: calc(13.5 / var(--rem-base) * 1rem);
693755
font-style: normal;
694-
height: 1.25em;
695756
line-height: 1.2;
696757
text-align: center;
697758
width: 1.25em;
759+
height: 1.25em;
698760
letter-spacing: -0.25ex;
699761
text-indent: -0.25ex;
700762
}

src/css/vars.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@
106106
--kbd-border-color: var(--color-gray-10);
107107
--pre-background: var(--panel-background);
108108
--pre-border-color: var(--panel-border-color);
109-
--pre-annotation-font-color: var(--color-gray-10);
109+
--pre-annotation-font-color: var(--color-gray-50);
110110
--quote-background: var(--panel-background);
111111
--quote-border-color: var(--color-gray-70);
112112
--quote-font-color: var(--color-gray-70);

src/js/07-copy-to-clipboard.js

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
;(function () {
2+
'use strict'
3+
4+
;[].slice.call(document.querySelectorAll('.doc pre.highlight, .doc .literalblock pre')).forEach(function (pre) {
5+
var code, language, lang, copy, toast, toolbox
6+
if (pre.classList.contains('highlight')) {
7+
code = pre.querySelector('code')
8+
if ((language = code.dataset.lang) && language !== 'console') {
9+
;(lang = document.createElement('span')).className = 'code-lang'
10+
lang.appendChild(document.createTextNode(language))
11+
}
12+
} else if (pre.innerText.startsWith('$ ')) {
13+
var block = pre.parentNode.parentNode
14+
block.classList.remove('literalblock')
15+
block.classList.add('listingblock')
16+
pre.classList.add('highlightjs')
17+
pre.classList.add('highlight')
18+
;(code = document.createElement('code')).className = 'language-console hljs'
19+
code.dataset.lang = 'console'
20+
code.appendChild(pre.firstChild)
21+
pre.appendChild(code)
22+
} else {
23+
return
24+
}
25+
;(copy = document.createElement('button')).className = 'copy-button'
26+
copy.setAttribute('title', 'Copy to clipboard')
27+
var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
28+
svg.setAttribute('class', 'copy-icon')
29+
svg.setAttribute('aria-hidden', 'true')
30+
svg.setAttribute('data-prefix', 'far')
31+
svg.setAttribute('data-icon', 'copy')
32+
svg.setAttribute('data-version', '5.10.2')
33+
svg.setAttribute('role', 'img')
34+
svg.setAttribute('viewBox', '0 0 448 512')
35+
var path = document.createElementNS('http://www.w3.org/2000/svg', 'path')
36+
path.setAttribute('fill', 'currentColor')
37+
path.setAttribute(
38+
'd',
39+
'M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z' // eslint-disable-line max-len
40+
)
41+
svg.appendChild(path)
42+
copy.appendChild(svg)
43+
;(toast = document.createElement('span')).className = 'copy-toast'
44+
toast.appendChild(document.createTextNode('Copied!'))
45+
copy.appendChild(toast)
46+
;(toolbox = document.createElement('div')).className = 'code-toolbox'
47+
if (lang) toolbox.appendChild(lang)
48+
toolbox.appendChild(copy)
49+
pre.appendChild(toolbox)
50+
copy.addEventListener('click', writeToClipboard.bind(copy, code))
51+
})
52+
53+
function writeToClipboard (code) {
54+
var text = code.innerText
55+
if (code.dataset.lang === 'console' && text.startsWith('$ ')) text = text.split('\n')[0].slice(2)
56+
window.navigator.clipboard.writeText(text).then(
57+
function () {
58+
this.classList.add('clicked')
59+
this.offsetHeight // eslint-disable-line no-unused-expressions
60+
this.classList.remove('clicked')
61+
}.bind(this),
62+
function () {}
63+
)
64+
}
65+
})()

src/partials/footer-content.hbs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
</div>
1414
<div class="footer-legal">
1515
<p>Except where noted, the content on this site is licensed under the Creative Commons Attribution 4.0 International (CC BY 4.0) license.</p>
16-
<p>The UI for this site is based on the default Antora UI and is thus licensed under the terms of the MPL-2.0 license.</p>
16+
<p>The UI for this site is based on the default Antora UI and is licensed under the MPL-2.0 license. Several icons are from <a href="https://fontawesome.com/license/free" target="_blank" rel="noopener">Font Awesome</a> and are licensed under the CC BY 4.0 license.</p>
1717
<p>AsciiDoc is a Trademark of the Eclipse Foundation, Inc.</p>
1818
</div>
1919
<div class="footer-thanks">

src/partials/header-content.hbs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
</div>
4646
<a class="navbar-item" href="https://twitter.com/asciidoctor" target="_blank" rel="noopener">
4747
<span class="icon">
48-
<svg aria-hidden="true" data-icon="twitter" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
48+
<svg aria-hidden="true" data-prefix="fab" data-icon="twitter" data-version="5.0.0" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
4949
<path fill="#57aaee" d="M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z"></path>
5050
</svg>
5151
</span>

0 commit comments

Comments
 (0)