Skip to content
Permalink
Browse files

Add code copy button to all code fields in the blog (#81)

  • Loading branch information
Sieboldianus authored and Track3 committed Aug 18, 2019
1 parent a9f2ddc commit 16c9d78ae518aebb65c3bca5871b2550bbabca16
@@ -13,6 +13,7 @@ Hermit is a minimal and fast theme for Hugo. It's built for bloggers who want a
* Featured image is supported. It will be displayed as a dimmed background of the page.
* Displays all of your posts on a single page, with one section per year, simple and compact.
* Extremely lightweight and load fast. No third party framework, no unnecessary code.
* All code fields feature syntax highlighting and a code-copy function
* Responsive & Retina Ready. Scales gracefully from a big screen all the way down to the smallest mobile phone. Assets in vector format ensures that it looks sharp on high-resolution screens.

**[Theme Demo](https://hugo-theme-hermit.netlify.com/)** (uses contents and config from the `exampleSite` folder)
@@ -111,5 +112,6 @@ You can inject any html code to every page's document head or right above the cl
* [normalize.css](https://necolas.github.io/normalize.css/) - [MIT](https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
* [animate.css](https://daneden.github.io/animate.css/) - [MIT](https://github.com/daneden/animate.css/blob/master/LICENSE)
* [feather](https://feathericons.com/) - [MIT](https://github.com/feathericons/feather/blob/master/LICENSE)
* [code-copy.js](assets/js/code-copy.js) - [Tom Spencer](https://www.fiznool.com/blog/2018/09/14/adding-click-to-copy-buttons-to-a-hugo-powered-blog/)

Thanks!
@@ -0,0 +1,56 @@
/**
* Utils
*/

// Add code-copy buttons using progressive enhancement
// © 2019. Tom Spencer
// https://www.fiznool.com/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');
Array.prototype.forEach.call(highlightBlocks, addCopyButton);
})();
@@ -153,6 +153,37 @@ table {
display: none;
}

// Code copy buttons
//

.highlight {
position: relative;
}

.highlight pre {

This comment has been minimized.

Copy link
@SteveHawk

SteveHawk Oct 21, 2019

This .highlight pre value is too large, causing issue #92

padding-right: 75px;
}

.highlight-copy-btn {
position: absolute;
bottom: 7px;
right: 7px;
border: 0;
border-radius: 4px;
padding: 1px;
font-size: 0.7em;
line-height: 1.8;
color: #fff;
background-color: #777;
opacity: 0.6;
min-width: 55px;
text-align: center;
}

.highlight-copy-btn:hover {
background-color: #666;
}

// Accessibility
//
.screen-reader-text {
@@ -48,6 +48,8 @@ enableEmoji = true # Shorthand emojis in content files - https://gohugo.io/func

relatedPosts = false # Add a related content section to all single posts page

code_copy_button = true # Turn on/off the code-copy-button for code-fields

# Add custom css
# customCSS = ["css/foo.css", "css/bar.css"]

@@ -30,8 +30,17 @@
{{ block "header" . -}}{{ end -}}
{{ block "main" . -}}{{ end -}}
{{ block "footer" . -}}{{ end }}
{{ $script := resources.Get "js/main.js" | minify | fingerprint -}}
<script src="{{ $script.Permalink }}" {{ printf "integrity=%q" $script.Data.Integrity | safeHTMLAttr }} crossorigin="anonymous"></script>

{{ $main := resources.Get "js/main.js" -}}
{{ if .Site.Params.code_copy_button | default true -}}
{{ $codeCopy := resources.Get "js/code-copy.js" -}}
{{ $script := slice $main $codeCopy | resources.Concat "js/bundle.js" | minify | fingerprint -}}
<script src="{{ $script.Permalink }}" {{ printf "integrity=%q" $script.Data.Integrity | safeHTMLAttr }} crossorigin="anonymous"></script>
{{ else -}}
{{ $script := $main | minify | fingerprint -}}
<script src="{{ $script.Permalink }}" {{ printf "integrity=%q" $script.Data.Integrity | safeHTMLAttr }} crossorigin="anonymous"></script>
{{ end }}

{{- partial "analytics.html" . }}
{{- if templates.Exists "partials/extra-foot.html" -}}
{{ partial "extra-foot.html" . }}
@@ -6,4 +6,8 @@ mobileMenuVisible=false;}}
const showImg=()=>{document.querySelector('.bg-img').classList.add('show-bg-img');}
const hideImg=()=>{document.querySelector('.bg-img').classList.remove('show-bg-img');}
const toggleToc=()=>{document.getElementById('toc').classList.toggle('show-toc');}
if(header!==null){listen('#menu-btn',"click",toggleMobileMenu);listen('#toc-btn',"click",toggleToc);listen('#img-btn',"click",showImg);listen('.bg-img',"click",hideImg);document.querySelectorAll('.post-year').forEach((ele)=>{ele.addEventListener('click',()=>{window.location.hash='#'+ele.id;});});window.addEventListener('scroll',throttle(()=>{autoHideHeader();if(mobileMenuVisible==true){toggleMobileMenu();}},250));}
if(header!==null){listen('#menu-btn',"click",toggleMobileMenu);listen('#toc-btn',"click",toggleToc);listen('#img-btn',"click",showImg);listen('.bg-img',"click",hideImg);document.querySelectorAll('.post-year').forEach((ele)=>{ele.addEventListener('click',()=>{window.location.hash='#'+ele.id;});});window.addEventListener('scroll',throttle(()=>{autoHideHeader();if(mobileMenuVisible==true){toggleMobileMenu();}},250));};(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);}
var highlightBlocks=document.getElementsByClassName('highlight');Array.prototype.forEach.call(highlightBlocks,addCopyButton);})();
@@ -0,0 +1 @@
{"Target":"js/bundle.min.4a9a0ac3d2217822c7865b4161e6c2a71de1d70492264337755427898dd718f6.js","MediaType":"application/javascript","Data":{"Integrity":"sha256-SpoKw9IheCLHhltBYebCpx3h1wSSJkM3dVQniY3XGPY="}}

This file was deleted.

0 comments on commit 16c9d78

Please sign in to comment.
You can’t perform that action at this time.