From d08971df1a355127c83a135d37655a5d43b8bdf1 Mon Sep 17 00:00:00 2001
From: Thomas Bui <thomasbui198@gmail.com>
Date: Sun, 19 Dec 2021 23:30:15 -0800
Subject: [PATCH] Add copy to clipboard button to website

---
 docs/assets/css/style.css | 39 +++++++++++++++++++++++------
 docs/assets/img/copy.svg  |  5 ++++
 docs/assets/js/script.js  | 44 +++++++++++++++++++++++++++++++++
 docs/index.html           | 52 ++++++++++++++++++++++++++++-----------
 4 files changed, 119 insertions(+), 21 deletions(-)
 create mode 100644 docs/assets/img/copy.svg

diff --git a/docs/assets/css/style.css b/docs/assets/css/style.css
index fe691c0f..dfc5af3a 100644
--- a/docs/assets/css/style.css
+++ b/docs/assets/css/style.css
@@ -350,6 +350,37 @@ header {
     header .icons-list img {
       max-width: 100%; }
 
+
+input[type='color'] {
+  width: 1.25em;
+  height: 1.25em;
+  margin-left: 0.5em;
+}
+
+.copyBtn {
+  height: 1.25em;
+  width: 1.25em;
+  margin-left: 0.25em;
+  position: relative;
+  top: 0.5em;
+  border-radius: 20%;
+  padding: 0.25em;
+  box-sizing: content-box;
+  transition: background-color 0.25s;
+}
+
+.copyBtn:hover {
+  cursor: pointer;
+  background-color: #2D804E;
+}
+
+.tooltip {
+  visibility: hidden;
+  background-color: #2D804E;
+  border-radius: 0.25em;
+  padding: 0.25em;
+}
+
 .borders {
   position: fixed;
   top: 0;
@@ -408,10 +439,4 @@ header {
 
 .footer {
   margin-top: 6rem;
-  text-align: center; }
-
-input[type='color'] {
-  width: 1.25em;
-  height: 1.25em;
-  margin-left: 0.5em;
-}
\ No newline at end of file
+  text-align: center; }
\ No newline at end of file
diff --git a/docs/assets/img/copy.svg b/docs/assets/img/copy.svg
new file mode 100644
index 00000000..2ee0e55f
--- /dev/null
+++ b/docs/assets/img/copy.svg
@@ -0,0 +1,5 @@
+<!-- Generated by IcoMoon.io -->
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
+<title>copy</title>
+<path fill="#f5f5f5" d="M20 8v-8h-14l-6 6v18h12v8h20v-24h-12zM6 2.828v3.172h-3.172l3.172-3.172zM2 22v-14h6v-6h10v6l-6 6v8h-10zM18 10.828v3.172h-3.172l3.172-3.172zM30 30h-16v-14h6v-6h10v20z"></path>
+</svg>
diff --git a/docs/assets/js/script.js b/docs/assets/js/script.js
index 33f5b3a0..3d8abc73 100644
--- a/docs/assets/js/script.js
+++ b/docs/assets/js/script.js
@@ -95,6 +95,7 @@ devicon.controller('IconListCtrl', function($scope, $http, $compile) {
 
   /*
   | Change selected icon
+  | param icon: the new icon.
   |--------------------------------
   */
   $scope.selectIcon = function(icon) {
@@ -158,6 +159,49 @@ devicon.controller('IconListCtrl', function($scope, $http, $compile) {
   }
 
   /*---- End of "Change selected svg icon" ----*/
+
+  /**
+   * Copy the text located using `id` into the user's clipboard.
+   * @param {Event} event - a JS Event object.
+   * @param {String} id - id of the element we are copying its text
+   * content from.
+   */
+  $scope.copyToClipboard = function(event, id) {
+    let text = document.getElementById(id).textContent
+    navigator.clipboard.writeText(text)
+      .then(() => {
+        $scope.displayTooltip("Copied", event.target)
+      })
+      .catch(() => {
+        $scope.displayTooltip("Failed to copy", event.target)
+      })
+  }
+
+  /**
+   * Display a tooltip.
+   * @param {String} text - text the tooltip should have.
+   * @param {Element} copyBtn - the copyBtn element, which is an <img>
+   */
+  $scope.displayTooltip = function(text, copyBtn) {
+    let tooltip = copyBtn.parentElement.getElementsByClassName("tooltip")[0]
+    tooltip.textContent = text
+    // reset opacity (for some reason, default opacity is null)
+    tooltip.style.opacity = 1
+    tooltip.style.visibility = "visible"
+
+    // create fade out effect after 2 sec
+    setTimeout(() => {
+      let count = 10
+      let intervalObj
+      intervalObj = setInterval(() => {
+        tooltip.style.opacity -= 0.1
+        if (--count == 0) {
+          clearInterval(intervalObj)
+          tooltip.style.visibility = "hidden"
+        } 
+      }, 50)
+    }, 2000)
+  }
 });
 
 /*================ End of "Devicons controller" ================*/
diff --git a/docs/index.html b/docs/index.html
index c3e1fad2..4071fddf 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -62,6 +62,17 @@
       <ul>
         <li>
           <h4>Font versions <input type='color' value='#60be86' ng-model="fontBackground"></h4>
+          <p>
+            Place this in your header (once per HTML file) 
+            <span>
+              <img src="./assets/img/copy.svg" class='copyBtn' ng-click="copyToClipboard($event, 'headerLinkCode')">
+              <span class='tooltip'></span>
+            </span>
+          </p>
+          <div class="cde" id='headerLinkCode'>
+            &lt;link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/devicons/devicon@{{ latestReleaseTagging }}/devicon.min.css"&gt;
+          </div>
+
           <ul class="icons-list">
             <div ng-repeat="fontVersion in selectedIcon.font">
               <li ng-click="selectFont(fontVersion, false, $index)" ng-class="{'selected-version' : ($index == selectedFontIndex && !colored)}" ng-style="{'background-color': fontBackground}">
@@ -72,16 +83,17 @@
               </li>
             </div>
           </ul>
-          <p>Place this in your header</p>
-          <div class="cde">
-            &lt;link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/devicons/devicon@{{ latestReleaseTagging }}/devicon.min.css"&gt;
-          </div>
-
-          <p>Use this in your body</p>
-          <div class="cde">
+          <p>
+            Place this in your body 
+            <span>
+              <img src="./assets/img/copy.svg" class='copyBtn' ng-click="copyToClipboard($event, 'iconClassCode')">
+              <span class='tooltip'></span>
+            </span>
+          </p>
+          <div class="cde" id="iconClassCode">
             &lt;i class="devicon-{{selectedIcon.name}}-{{selectedFontIcon}}<span ng-if="colored"> colored</span>"&gt;&lt;/i&gt;<br />
           </div>
-          <p><i>*To change the size, change the <code>i</code>'s <code>font-size</code></i></p>
+          <p><i>*To change the size, change the <code>i</code> element's <code>font-size</code> attribute.</i></p>
         </li>
         <li>
           <h4>SVG versions <input type='color' value='#60be86' ng-model="svgBackground"></h4>
@@ -90,21 +102,33 @@
               <img ng-src="https://cdn.jsdelivr.net/gh/devicons/devicon/icons/{{selectedIcon.name}}/{{selectedIcon.name}}-{{svgVersion}}.svg">
             </li>
           </ul>
-          <p>Using &lt;img&gt; element</p>
-          <div class="cde">
+          <p>
+            Using &lt;img&gt; element 
+            <span>
+              <img src="./assets/img/copy.svg" class='copyBtn' ng-click="copyToClipboard($event, 'imgCode')">
+              <span class='tooltip'></span>
+            </span>
+          </p>
+          <div class="cde" id='imgCode'>
             &lt;img src="https://cdn.jsdelivr.net/gh/devicons/devicon/icons/{{selectedIcon.name}}/{{selectedIcon.name}}-{{selectedIcon.svg[selectedSvgIndex]}}.svg" /&gt;<br />
           </div>
-          <p><i>*To change the size, change the <code>img</code>'s <code>height</code> and <code>width</code></i></p>
+          <p><i>*To change the size, change the <code>img</code>'s <code>height</code> and <code>width</code> attributes.</i></p>
 
           <br />
 
-          <p>Using Pure SVG</p>
-          <div class="cde">
+          <p>
+            Using Pure SVG 
+            <span>
+              <img src="./assets/img/copy.svg" class='copyBtn' ng-click="copyToClipboard($event, 'svgCode')">
+              <span class='tooltip'></span>
+            </span>
+          </p>
+          <div class="cde" id='svgCode'>
             &lt;svg viewBox="0 0 128 128"&gt;<br />
             <div class="cde-ind">{{selectedSvgIcon}}</div>
             &lt;/svg&gt;
           </div>
-          <p><i>*To change the size, change the <code>svg</code>'s <code>height</code> and <code>width</code></i></p>
+          <p><i>*To change the size, change the <code>svg</code>'s <code>height</code> and <code>width</code> attributes.</i></p>
         </li>
       </ul>