git: 0188b57bf9 - main - Add copy button to source code elements

From: Sergio Carlavilla Delgado <carlavilla_at_FreeBSD.org>
Date: Sun, 10 Apr 2022 10:20:06 UTC
The branch main has been updated by carlavilla:

URL: https://cgit.FreeBSD.org/doc/commit/?id=0188b57bf9aa69736f1ce710fa798c208940cb9d

commit 0188b57bf9aa69736f1ce710fa798c208940cb9d
Author:     Sergio Carlavilla Delgado <carlavilla@FreeBSD.org>
AuthorDate: 2022-04-10 10:17:26 +0000
Commit:     Sergio Carlavilla Delgado <carlavilla@FreeBSD.org>
CommitDate: 2022-04-10 10:19:44 +0000

    Add copy button to source code elements
    
    A copy button has been added to all source code elements.
    It works using Javascript so Javascript should be
    activated in the browser.
---
 .../themes/beastie/assets/js/copy-clipboard.js     | 66 ++++++++++++++++++++++
 .../themes/beastie/assets/styles/global.scss       | 56 ++++++++++++++++++
 .../themes/beastie/assets/styles/variables.scss    |  3 +
 .../themes/beastie/layouts/partials/site-head.html |  6 ++
 4 files changed, 131 insertions(+)

diff --git a/documentation/themes/beastie/assets/js/copy-clipboard.js b/documentation/themes/beastie/assets/js/copy-clipboard.js
new file mode 100644
index 0000000000..4b11058422
--- /dev/null
+++ b/documentation/themes/beastie/assets/js/copy-clipboard.js
@@ -0,0 +1,66 @@
+/*
+BSD 2-Clause License
+
+Copyright (c) 2001-2022, The FreeBSD Documentation Project
+Copyright (c) 2021-2022, Sergio Carlavilla
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+   list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+(function () {
+  document.querySelectorAll(".rouge, .highlight").forEach(function(codeItem) {
+    var sourceCode = codeItem.textContent;
+
+    var icon = document.createElement("i");
+    icon.className = "fa fa-clipboard";
+
+    var tooltip = document.createElement("span");
+    tooltip.className = "tooltip";
+    tooltip.innerHTML = "Copied!";
+
+    var button = document.createElement("button");
+    button.title = "Copy to clipboard";
+    button.appendChild(icon);
+    button.appendChild(tooltip);
+
+    var clipboardWrapper = document.createElement("div");
+    clipboardWrapper.className = "copy-to-clipboard-wrapper";
+    clipboardWrapper.appendChild(button);
+
+    codeItem.appendChild(clipboardWrapper);
+
+    button.addEventListener('click', copyToClipboard.bind(button, sourceCode));
+  });
+})();
+
+function copyToClipboard(text, item) {
+  const tooltip = item.target.nextElementSibling;
+  window.navigator.clipboard.writeText(text).then(function() {
+    if (tooltip) {
+      tooltip.classList.add("show-tooltip");
+      setTimeout(function(){
+        tooltip.classList.remove("show-tooltip");
+      }, 1200);
+    }
+  });
+}
diff --git a/documentation/themes/beastie/assets/styles/global.scss b/documentation/themes/beastie/assets/styles/global.scss
index 9873fbc46e..e2172bbcf9 100644
--- a/documentation/themes/beastie/assets/styles/global.scss
+++ b/documentation/themes/beastie/assets/styles/global.scss
@@ -688,6 +688,12 @@ table.stretch {
 
 .listingblock {
   margin: .75em 0;
+  position: relative;
+}
+
+.highlight {
+  padding-top: 1.5rem;
+  padding-bottom: 1.5rem;
 }
 
 code {
@@ -738,3 +744,53 @@ kbd {
     color: var(--global-font-color);
   }
 }
+
+.copy-to-clipboard-wrapper {
+  position: absolute;
+  margin: 0;
+  padding: .50rem;
+  right: .5rem;
+  top: 0rem;
+
+  button {
+    display: flex;
+    flex-direction: column;
+    border: none;
+    cursor: pointer;
+    align-items: center;
+    width: 1rem;
+    height: 1rem;
+    background: none;
+
+    &:focus {
+      outline: none;
+    }
+
+    i {
+      color: var(--white);
+    }
+  }
+
+  .tooltip {
+    visibility: hidden;
+    opacity: 0;
+    justify-content: center;
+    margin-top: 1em;
+    background-color: var(--copy-clipboard-tooltip-background-color);
+    border-radius: .25em;
+    padding: .5em;
+    color: var(--white);
+    z-index: 999;
+
+    &:focus {
+      outline: none;
+    }
+  }
+
+  .show-tooltip {
+    visibility: visible;
+    opacity: 1;
+    transition: visibility 0s easy 0s;
+  }
+
+}
diff --git a/documentation/themes/beastie/assets/styles/variables.scss b/documentation/themes/beastie/assets/styles/variables.scss
index adb22109e1..48a87f7c14 100644
--- a/documentation/themes/beastie/assets/styles/variables.scss
+++ b/documentation/themes/beastie/assets/styles/variables.scss
@@ -60,6 +60,7 @@
   --links-color: #0645AD;
   --pre-background-color: #F4F4F4;
   --pre-font-color: #444;
+  --copy-clipboard-tooltip-background-color: #43453B;
 
   --admonition-font-color: #444;
   --admonition-links-color: #0645AD;
@@ -95,6 +96,7 @@
   --links-color: #BAD7FF;
   --pre-background-color: #272727;
   --pre-font-color: #EEEFF1;
+  --copy-clipboard-tooltip-background-color: #43453B;
 
   --admonition-font-color: #444;
   --admonition-links-color: #1A79FF;
@@ -130,6 +132,7 @@
   --links-color: #9F0E0F;
   --pre-background-color: #FFF;
   --pre-font-color: #000;
+  --copy-clipboard-tooltip-background-color: #43453B;
 
   --admonition-font-color: #000;
   --admonition-note-color: #19407C;
diff --git a/documentation/themes/beastie/layouts/partials/site-head.html b/documentation/themes/beastie/layouts/partials/site-head.html
index 781ad79c12..e20572e820 100644
--- a/documentation/themes/beastie/layouts/partials/site-head.html
+++ b/documentation/themes/beastie/layouts/partials/site-head.html
@@ -20,6 +20,9 @@
 
     {{- $themeChooser := resources.Get "js/theme-chooser.js" | resources.Minify }}
     <script defer src="{{ $themeChooser.RelPermalink }}"></script>
+
+    {{- $copyClipboard := resources.Get "js/copy-clipboard.js" | resources.Minify }}
+    <script defer src="{{ $copyClipboard.RelPermalink }}"></script>
   {{ else }}
     <link rel="shortcut icon" href="/favicon.ico">
 
@@ -29,6 +32,9 @@
 
     {{- $themeChooser := resources.Get "js/theme-chooser.js" | resources.Minify }}
     <script defer src="{{ $themeChooser.RelPermalink }}"></script>
+
+    {{- $copyClipboard := resources.Get "js/copy-clipboard.js" | resources.Minify }}
+    <script defer src="{{ $copyClipboard.RelPermalink }}"></script>
   {{ end }}
 
   <!-- SEO -->