From 3b31711b4992c5c784180949546cda8697b8e85b Mon Sep 17 00:00:00 2001 From: interlope Date: Tue, 2 Jun 2026 23:52:15 +0200 Subject: [PATCH] feat: add copy button to tab bar for easy code copying functionality --- css/style.css | 25 +++++++++++++++++++++++++ js/blowdit.js | 30 ++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/css/style.css b/css/style.css index 4b55a2d..ee6e9a1 100644 --- a/css/style.css +++ b/css/style.css @@ -1339,6 +1339,31 @@ footer.footer-modern a:hover { border-bottom-color: var(--accent); } +/* Copy button pinned to the right of the tab bar (copies the active tab) */ +.tab-copy { + align-self: center; + margin-left: auto; + flex: 0 0 auto; + display: inline-flex; + align-items: center; + gap: 0.35rem; + padding: 0.25rem 0.7rem; + border: none; + background: transparent; + color: var(--text-muted); + font-size: var(--font-size-xs); + font-weight: 600; + font-family: var(--font-sans); + white-space: nowrap; + cursor: pointer; + transition: color 0.15s ease; +} + +.tab-copy:hover { color: var(--text-primary); } +.tab-copy.is-copied { color: var(--accent); } +.tab-copy svg { display: block; } +.tab-copy-label { line-height: 1; } + .tab-panel { display: none; } diff --git a/js/blowdit.js b/js/blowdit.js index e960df7..db31f32 100644 --- a/js/blowdit.js +++ b/js/blowdit.js @@ -276,6 +276,13 @@ -------------------------------------------------------- */ (function () { var tabGroupSeq = 0; + var TAB_COPY = '' + + ''; + var TAB_CHECK = ''; // Match both "language-tabs" (Parsedown >= 1.7) and bare "tabs" (older Bludit builds) var blocks = document.querySelectorAll( 'pre > code.language-tabs, pre > code.tabs' @@ -378,6 +385,29 @@ }); }); + // One copy button in the tab bar — copies whichever tab is active. + var tabCopy = document.createElement('button'); + tabCopy.type = 'button'; + tabCopy.className = 'tab-copy'; + tabCopy.setAttribute('aria-label', T.copyCode); + tabCopy.innerHTML = TAB_COPY + '' + T.copy + ''; + list.appendChild(tabCopy); + + var tabCopyTimer = null; + tabCopy.addEventListener('click', function () { + var activePanel = group.querySelector('.tab-panel.is-active'); + var activeCode = activePanel ? activePanel.querySelector('code') : null; + copyToClipboard(activeCode ? activeCode.textContent : '').then(function () { + tabCopy.classList.add('is-copied'); + tabCopy.innerHTML = TAB_CHECK + '' + T.copied + ''; + clearTimeout(tabCopyTimer); + tabCopyTimer = setTimeout(function () { + tabCopy.classList.remove('is-copied'); + tabCopy.innerHTML = TAB_COPY + '' + T.copy + ''; + }, 1200); + }).catch(function () {}); + }); + pre.parentNode.replaceChild(group, pre); }); })();