From 703556d2381521fde27f21f6f7baa9ee5e739b9b Mon Sep 17 00:00:00 2001 From: realaravinth Date: Tue, 4 Oct 2022 18:09:44 +0530 Subject: [PATCH] feat: copy code to clipboard on blog posts --- sass/blog/main.scss | 14 +++++++ static/icons/check.svg | 1 + static/icons/clipboard.svg | 1 + static/js/copy.js | 79 ++++++++++++++++++++++++++++++++++++++ templates/base.html | 3 ++ templates/blog/post.html | 1 + 6 files changed, 99 insertions(+) create mode 100644 static/icons/check.svg create mode 100644 static/icons/clipboard.svg create mode 100644 static/js/copy.js diff --git a/sass/blog/main.scss b/sass/blog/main.scss index ef76b91..2a3da05 100644 --- a/sass/blog/main.scss +++ b/sass/blog/main.scss @@ -85,3 +85,17 @@ $std-trans: 0.3s; margin: 5px !important; } } + +.copy-code { + margin: auto; + margin-top: 0; + cursor: pointer; +} + +.blog__content pre { + display: flex; +} + +.blog__content code { + flex: auto; +} diff --git a/static/icons/check.svg b/static/icons/check.svg new file mode 100644 index 0000000..09e07ea --- /dev/null +++ b/static/icons/check.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/icons/clipboard.svg b/static/icons/clipboard.svg new file mode 100644 index 0000000..b02f56b --- /dev/null +++ b/static/icons/clipboard.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/js/copy.js b/static/js/copy.js new file mode 100644 index 0000000..7628faa --- /dev/null +++ b/static/js/copy.js @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2022 Aravinth Manivannan + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +const check_dataset = (id, property) => { + let elem = document.getElementById(id); + if (elem === undefined || elem == null) { + console.warn(`${id} not found`); + return false; + } + if (!elem.dataset.hasOwnProperty(property)) { + console.warn(`${id} component doesn't have ${property} dataset attribute`); + return false; + } + + return elem; +}; + +const init_clipboard = () => { + const CHECK_COMPONENT = check_dataset("check-icon", "check"); + if (CHECK_COMPONENT == false) { + return; + } + const CHECK_ICON = CHECK_COMPONENT.dataset.check; + + const CLIPBOARD_COMPONET = check_dataset("clipboard-icon", "clipboard"); + if (CLIPBOARD_COMPONET == false) { + return; + } + const CLIPBOARD_ICON = CLIPBOARD_COMPONET.dataset.clipboard; + + const copy_code = async (event) => { + const switch_clipboard_icon = async (event) => { + event.target.src = CHECK_ICON; + setTimeout(() => { + event.target.src = CLIPBOARD_ICON; + }, 1200); + }; + + let elem = event.target; + let codes = Array.from(elem.parentElement.getElementsByTagName("span")); + let content = ""; + codes.forEach((span) => { + content = `${content} ${span.innerText}`; + }); + + await navigator.clipboard.writeText(content); + await switch_clipboard_icon(event); + }; + + const new_clipboard = () => { + let clipboard = document.createElement("img"); + clipboard.src = CLIPBOARD_ICON; + clipboard.classList = ["copy-code"]; + clipboard.addEventListener("click", copy_code); + return clipboard; + }; + + document.querySelectorAll("code").forEach((code) => { + if (code.parentElement.tagName == "PRE") { + code.parentElement.appendChild(new_clipboard()); + } + }); +}; + +init_clipboard(); diff --git a/templates/base.html b/templates/base.html index 45f10b2..5ff84d4 100644 --- a/templates/base.html +++ b/templates/base.html @@ -16,6 +16,7 @@ href="{{ get_url(path='/mobile.css') }}" /> + @@ -50,6 +51,8 @@ +
+
{% include "nav.html" %}
diff --git a/templates/blog/post.html b/templates/blog/post.html index 2e73c1b..a6855aa 100644 --- a/templates/blog/post.html +++ b/templates/blog/post.html @@ -19,4 +19,5 @@ endblock meta %} {% block content %} + {% endblock content %}