From 6d16ef93c5f524b52c96b5996f3e4669d6c857ec Mon Sep 17 00:00:00 2001 From: marko-bekhta Date: Fri, 9 May 2025 10:09:02 +0200 Subject: [PATCH] Add copy-to-clipboard --- _config/site.yml | 4 +++ _layouts/base.html.haml | 44 ++++++++++++++++++++++++++ _partials/head.html.haml | 1 + stylesheets/styles.scss | 68 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 117 insertions(+) diff --git a/_config/site.yml b/_config/site.yml index 6c5ec7be..d9da94d0 100644 --- a/_config/site.yml +++ b/_config/site.yml @@ -38,6 +38,8 @@ semantic_ui_css_url: https://cdn.jsdelivr.net/npm/semantic-ui@2.2.14/dist/semant slick_js_url: https://cdn.jsdelivr.net/npm/slick-carousel@1.7.1/slick/slick slick_js_url_integrity: "sha384-wBo76R9TGH6DxuCcambHkpxJKY96xJq59OwZONC0A2v0rlNK9Kb75uRdSgxK5j9+" slick_css_url: https://cdn.jsdelivr.net/npm/slick-carousel@1.7.1/slick/slick +clipboard_js_url: https://cdn.jsdelivr.net/npm/clipboard@2.0.11/dist/clipboard +clipboard_js_url_integrity: "sha256-4XodgW4TwIJuDtf+v6vDJ39FVxI0veC/kSCCmnFp7ck=" jborg_fonts_url: https://static.jboss.org/theme/fonts jborg_images_url: https://static.jboss.org/theme/images @@ -754,6 +756,7 @@ profiles: jquery_js_url_integrity: "sha384-VC7EHu0lDzZyFfmjTPJq+DFyIn8TUGAJbEtpXquazFVr00Q/OOx//RjiZ9yU9+9m" semantic_ui_js_url_integrity: "sha384-/OCHdyuUZjDPStDj7ti/VaVeGQ4U9HxuJhh0FNfMTf0eO1VeBLAam8EiKCIK+jso" slick_js_url_integrity: "sha384-vIgLoBvIiHAJ0ttXa/pf/vpP9JgaN/9dCH6zbhDPEF3H8fvQXE0wHjS/LauoTNF1" + clipboard_js_url_integrity: "sha256-ul94Jn0MBOijGuvXhgx/1/wjaJHN3Ud6TH/cGaDrF24=" base_url: http://0.0.0.0:4242 news_feed_root_url: https://staging.in.relation.to/feeds test: @@ -764,6 +767,7 @@ profiles: jquery_js_url_integrity: "sha384-VC7EHu0lDzZyFfmjTPJq+DFyIn8TUGAJbEtpXquazFVr00Q/OOx//RjiZ9yU9+9m" semantic_ui_js_url_integrity: "sha384-/OCHdyuUZjDPStDj7ti/VaVeGQ4U9HxuJhh0FNfMTf0eO1VeBLAam8EiKCIK+jso" slick_js_url_integrity: "sha384-vIgLoBvIiHAJ0ttXa/pf/vpP9JgaN/9dCH6zbhDPEF3H8fvQXE0wHjS/LauoTNF1" + clipboard_js_url_integrity: "sha256-ul94Jn0MBOijGuvXhgx/1/wjaJHN3Ud6TH/cGaDrF24=" base_url: http://0.0.0.0:4242 news_feed_root_url: https://in.relation.to/feeds staging: diff --git a/_layouts/base.html.haml b/_layouts/base.html.haml index 82ad6254..982a651e 100644 --- a/_layouts/base.html.haml +++ b/_layouts/base.html.haml @@ -58,3 +58,47 @@ $('body, html').animate({scrollTop:0}, 800); }); }); + + :javascript + /* + * This is an adapted version of https://github.com/quarkusio/quarkusio.github.io/blob/317db07ca629dc331455692d2976ecece95319cd/assets/javascript/copy.js + */ + const codes = document.querySelectorAll('pre.highlight > code'); + let index = 0; + codes.forEach((code) => { + + code.setAttribute("id", "code" + index); + + const block = document.createElement('div'); + block.className = "tooltip"; + + const btn = document.createElement('i'); + btn.className = "btn-copy ui copy outline icon"; + btn.setAttribute("data-clipboard-action", "copy"); + btn.setAttribute("data-clipboard-target", "#code" + index); + btn.setAttribute("title", "Copy to clipboard"); + btn.setAttribute("float-right", "true"); + code.before(btn); + + const tooltip = document.createElement('div'); + tooltip.className = "tooltip-text"; + tooltip.textContent = "Copied!"; + code.before(tooltip); + + index++; + }); + + const clipboard = new ClipboardJS('.btn-copy'); + clipboard.on('success', function (e) { + e.clearSelection(); + e.trigger.className = e.trigger.className.replace("copy outline icon", "check icon"); + e.trigger.setAttribute("title", "Copied!"); + e.trigger.nextSibling.classList.toggle("show"); + e.trigger.blur(); + + setTimeout(function () { + e.trigger.className = e.trigger.className.replace("check icon", "copy outline icon"); + e.trigger.setAttribute("title", "Copy to clipboard"); + e.trigger.nextSibling.classList.toggle("show"); + }, 1500); + }); diff --git a/_partials/head.html.haml b/_partials/head.html.haml index 935e8b95..dafb2072 100644 --- a/_partials/head.html.haml +++ b/_partials/head.html.haml @@ -40,6 +40,7 @@ %link(href="https://fonts.googleapis.com/css2?family=Inconsolata:wght@400;700&display=swap" rel="stylesheet") %script(src="#{site.jquery_js_url}#{site.minified}.js" crossorigin="anonymous" type="text/javascript" integrity="#{site.jquery_js_url_integrity}") %script(src="#{site.semantic_ui_js_url}#{site.minified}.js" crossorigin="anonymous" type="text/javascript" integrity="#{site.semantic_ui_js_url_integrity}") +%script(src="#{site.clipboard_js_url}#{site.minified}.js" crossorigin="anonymous" type="text/javascript" integrity="#{site.clipboard_js_url_integrity}") - if real_page.javascripts - real_page.javascripts.each do |javascript| %script{:src=>javascript, :type=>'text/javascript'} diff --git a/stylesheets/styles.scss b/stylesheets/styles.scss index bdd81b80..168ac7f9 100644 --- a/stylesheets/styles.scss +++ b/stylesheets/styles.scss @@ -1016,3 +1016,71 @@ pre .comment .conum { } } +// copy to clipboard: + +pre.highlight { + position: relative; + + .btn-copy { + cursor: pointer; + transition: opacity 0.3s ease-in-out; + opacity: 0; + padding: 2px 6px; + position: absolute; + right: 0.825rem; + top: 0.025rem; + background-color: transparent; + border: none; + + &:focus { + opacity: 0.5; + } + } +} + +.listingblock { + &:hover { + .btn-copy { + opacity: 0.5; + } + + code[data-lang]::before { + opacity: 0.5; + } + + .tooltip-text.show { + opacity: 1; + } + } + + code[data-lang] { + &::before { + display: block; + content: attr(data-lang) '|'; + top: .425rem; + right: 2.2rem; + transition: opacity 0.3s ease-in-out; + opacity: 0; + position: absolute; + font-size: .75em; + line-height: 1; + text-transform: uppercase; + color: inherit; + } + } +} + +.tooltip-text { + display: block; + position: absolute; + top: 1.5rem; + right: 4px; + background: #444; + color: #fff; + padding: 6px 10px; + border-radius: 4px; + white-space: nowrap; + z-index: 1; + opacity: 0; + font-size: 11px; +}