From 134127da86d4796f5eb391383a5a9b99355a6024 Mon Sep 17 00:00:00 2001 From: Geri Ochoa Date: Mon, 27 Feb 2023 14:59:14 -0500 Subject: [PATCH] Refactor Click-to-copy with Bootstrap5 Refactor of PR #1245. Bootstrap5-compatible code. --- CHANGELOG.md | 8 +- assets/js/click-to-copy.js | 111 ++++++------------ assets/scss/_code.scss | 22 +--- layouts/partials/scripts.html | 2 +- .../en/docs/adding-content/lookandfeel.md | 5 + 5 files changed, 52 insertions(+), 96 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ef4f984dd..c3f01ce89e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,11 @@ For a list of issues targeted for the next release, see the [23Q1][] milestone. **New**: -**Breaking changes**: +- **Click to copy button for Chroma-highlighted code blocks**: If you already + implemented this functionality on your website, you can disable it. For + details see [Chroma highlighting docs][chroma-docsy]. + +**Breaking changes:** - **Upgraded Bootstrap ([#470])** to v5.2. For a list of Bootstrap's breaking changes, see the [Bootstrap migration guide][bsv5mig]. Other Docsy-specific @@ -37,6 +41,8 @@ For a list of issues targeted for the next release, see the [23Q1][] milestone. - `card-code` is deprecated; use `card` with named parameter `code=true` instead. +[chroma-docsy]: https://www.docsy.dev/docs/adding-content/lookandfeel/#code-highlighting-with-chroma + **Other changes**: - `$list-inline-padding` is increased in support of footer icons ([#1523]). If diff --git a/assets/js/click-to-copy.js b/assets/js/click-to-copy.js index 5fdb041a86..0616fe4b21 100644 --- a/assets/js/click-to-copy.js +++ b/assets/js/click-to-copy.js @@ -1,86 +1,47 @@ let codeListings = document.querySelectorAll('.highlight > pre'); -for (let index = 0; index < codeListings.length; index++) -{ +for (let index = 0; index < codeListings.length; index++) { const codeSample = codeListings[index].querySelector('code'); - const copyButton = document.createElement("button"); - copyButton.setAttribute('type', 'button'); - copyButton.onclick = function() { copyCode(codeSample); }; - copyButton.classList.add('fas', 'fa-copy'); + const copyButton = document.createElement('button'); + const buttonAttributes = { + type: 'button', + title: 'Copy to clipboard', + 'data-bs-toggle': 'tooltip', + 'data-bs-placement': 'top', + 'data-bs-container': 'body', + }; + + Object.keys(buttonAttributes).forEach((key) => { + copyButton.setAttribute(key, buttonAttributes[key]); + }); - const buttonTooltip = document.createElement('div'); - buttonTooltip.classList.add('c2c-tooltip'); - buttonTooltip.setAttribute('role', 'tooltip'); - buttonTooltip.innerHTML += 'Copy to clipboard'; + copyButton.classList.add( + 'fas', + 'fa-copy', + 'btn', + 'btn-dark', + 'btn-sm', + 'td-click-to-copy' + ); + const tooltip = new bootstrap.Tooltip(copyButton); + + copyButton.onclick = () => { + copyCode(codeSample); + copyButton.setAttribute('data-bs-original-title', 'Copied!'); + tooltip.show(); + }; + + copyButton.onmouseout = () => { + copyButton.setAttribute('data-bs-original-title', 'Copy to clipboard'); + tooltip.hide(); + }; const buttonDiv = document.createElement('div'); buttonDiv.classList.add('click-to-copy'); - - // Use Popper to create and handle the tooltip behavior. - - const popperInstance = Popper.createPopper(copyButton, buttonTooltip, - { - modifiers: - [ - { - name: 'offset', - options: - { - offset: [0, -48], - }, - }, - ], - }); - - copyButton.addEventListener('click', () => - { - buttonTooltip.innerHTML = 'Copied!'; - }); - - copyButton.addEventListener('mouseenter', () => - { - buttonTooltip.setAttribute('show-tooltip', ''); - - // Enable eventListeners when the code block is on the viewport - - popperInstance.setOptions((options) => ({ - ...options, - modifiers: - [ - ...options.modifiers, - { name: 'eventListeners', enabled: true }, - ], - })); - popperInstance.update(); - }); - - copyButton.addEventListener('mouseleave', () => - { - buttonTooltip.removeAttribute('show-tooltip'); - - // Reset the message in case the button was clicked - buttonTooltip.innerHTML = 'Copy to clipboard'; - - // Disble eventListeners when the code block is NOT on the viewport - - popperInstance.setOptions((options) => ({ - ...options, - modifiers: - [ - ...options.modifiers, - { name: 'eventListeners', enabled: false }, - ], - })); - }); - buttonDiv.append(copyButton); - buttonDiv.append(buttonTooltip); codeListings[index].insertBefore(buttonDiv, codeSample); - -} - -function copyCode(codeSample) -{ - navigator.clipboard.writeText(codeSample.textContent.trim()); } +const copyCode = (codeSample) => { + navigator.clipboard.writeText(codeSample.textContent.trim() + '\n'); +}; diff --git a/assets/scss/_code.scss b/assets/scss/_code.scss index 759c7e5634..fefc4e7306 100644 --- a/assets/scss/_code.scss +++ b/assets/scss/_code.scss @@ -21,15 +21,15 @@ // Default click-to-copy button - button { + button.td-click-to-copy { position: absolute; color: $gray-400; border-radius: 3px; border-width: 0; background-color: inherit; box-shadow: 1px 1px $gray-400; - right: 8px; - top: 6px; + right: 4px; + top: 2px; &:hover { color: $dark; @@ -41,22 +41,6 @@ transform: translateY(2px); } } - - .c2c-tooltip { - background: $dark; - color: $white; - padding: 2px 4px; - border-radius: 3px; - display: block; - visibility: hidden; - opacity: 0; - transition: visibility 0s, opacity 0.5s linear; - } - - .c2c-tooltip[show-tooltip] { - visibility: visible; - opacity: 1; - } } } diff --git a/layouts/partials/scripts.html b/layouts/partials/scripts.html index 8e1d386ceb..e905025e40 100644 --- a/layouts/partials/scripts.html +++ b/layouts/partials/scripts.html @@ -91,7 +91,7 @@ {{ if .Site.Params.prism_syntax_highlighting -}} -{{ else if false -}} +{{ else if ( not .Site.Params.disable_click2copy_chroma ) -}} {{ $c2cJS := resources.Get "js/click-to-copy.js" -}} {{ if hugo.IsProduction -}} {{ $c2cJS = $c2cJS | minify | fingerprint -}} diff --git a/userguide/content/en/docs/adding-content/lookandfeel.md b/userguide/content/en/docs/adding-content/lookandfeel.md index 699724b0e4..9e46c4a9c9 100644 --- a/userguide/content/en/docs/adding-content/lookandfeel.md +++ b/userguide/content/en/docs/adding-content/lookandfeel.md @@ -144,6 +144,11 @@ guessSyntax: true {{< /tab >}} {{< /tabpane >}} +If you are using a Docsy version later than `0.6.0`, the code blocks show a +"Copy to clipboard" icon in the top right-hand corner. To disable this +functionality set `disable_click2copy_chroma` to `true` in your configuration +file: + You can find out more about code highlighting in Hugo with Chroma in [Syntax Highlighting](https://gohugo.io/content-management/syntax-highlighting/). ## Code highlighting with Prism