summaryrefslogtreecommitdiff
path: root/static/js/copyCodeToClipboard.js
diff options
context:
space:
mode:
authorAlejandro Soto <alejandro@34project.org>2025-09-13 14:55:15 -0600
committerAlejandro Soto <alejandro@34project.org>2025-09-13 14:55:15 -0600
commita2ea06d513a5802964f8f0ef5795cec7e548ed7b (patch)
tree8afb58e3749d19bc46cffc6473f3059d647c515b /static/js/copyCodeToClipboard.js
Squashed 'themes/tabi-lean/' content from commit 95c8796
git-subtree-dir: themes/tabi-lean git-subtree-split: 95c879696445ede40daa7a30a88dae5dd74d5c0c
Diffstat (limited to '')
-rw-r--r--static/js/copyCodeToClipboard.js47
1 files changed, 47 insertions, 0 deletions
diff --git a/static/js/copyCodeToClipboard.js b/static/js/copyCodeToClipboard.js
new file mode 100644
index 0000000..805eb59
--- /dev/null
+++ b/static/js/copyCodeToClipboard.js
@@ -0,0 +1,47 @@
+const copiedText = document.getElementById('copy-success').textContent;
+const initCopyText = document.getElementById('copy-init').textContent;
+
+const changeIcon = (copyDiv, className) => {
+ copyDiv.classList.add(className);
+ copyDiv.setAttribute('aria-label', copiedText);
+ setTimeout(() => {
+ copyDiv.classList.remove(className);
+ copyDiv.setAttribute('aria-label', initCopyText);
+ }, 2500);
+};
+
+const addCopyEventListenerToDiv = (copyDiv, block) => {
+ copyDiv.addEventListener('click', () => copyCodeAndChangeIcon(copyDiv, block));
+};
+
+const copyCodeAndChangeIcon = async (copyDiv, block) => {
+ const code = block.querySelector('table')
+ ? getTableCode(block)
+ : getNonTableCode(block);
+ try {
+ await navigator.clipboard.writeText(code);
+ changeIcon(copyDiv, 'checked');
+ } catch (error) {
+ changeIcon(copyDiv, 'error');
+ }
+};
+
+const getNonTableCode = (block) => {
+ return [...block.querySelectorAll('code')].map((code) => code.textContent).join('');
+};
+
+const getTableCode = (block) => {
+ return [...block.querySelectorAll('tr')]
+ .map((row) => row.querySelector('td:last-child')?.innerText ?? '')
+ .join('');
+};
+
+document.querySelectorAll('pre:not(.mermaid)').forEach((block) => {
+ const copyDiv = document.createElement('div');
+ copyDiv.setAttribute('role', 'button');
+ copyDiv.setAttribute('aria-label', initCopyText);
+ copyDiv.setAttribute('title', initCopyText);
+ copyDiv.className = 'copy-code';
+ block.prepend(copyDiv);
+ addCopyEventListenerToDiv(copyDiv, block);
+});