I am trying to integrate a basic, "copy to clipboard" function with Rainbow syntax highlighting library. Each code snippet on the page receives highlighting and can be copied to the clipboard by clicking a "Copy" button. Copy buttons are a common functionality, and I don't want to use another plugin for something this simple. I have tried using the Clipboard API script below which works fine on it's own, but when Rainbow is running, the copy function no longer works (and no errors are thrown in the console). Can anyone help me integrate the script below with Rainbow's highlighting library?
Rainbow Repository: https://github.com/ccampbell/rainbow
Example of Raw HTML:
<pre class="lang-html" tabindex="0"><code data-language="html">
<div class="container">
<div class="row">
<div class="col">Column 1</div>
<div class="col">Column 2</div>
<div class="col">Column 3</div>
</div>
</div>
</code></pre>
Example of Raw HTML output with Rainbow:
<pre class="lang-html rainbow-show" tabindex="0" data-trimmed="true"><code data-language="html" class="rainbow rainbow-show">
<span class="support tag"><span class="support tag"><</span><span class="support tag-name">div</span></span> <span class="support attribute">class</span><span class="support operator">=</span><span class="string quote">"</span><span class="string value">container</span><span class="string quote">"</span><span class="support tag close">></span>
<span class="support tag"><span class="support tag"><</span><span class="support tag-name">div</span></span> <span class="support attribute">class</span><span class="support operator">=</span><span class="string quote">"</span><span class="string value">row</span><span class="string quote">"</span><span class="support tag close">></span>
<span class="support tag"><span class="support tag"><</span><span class="support tag-name">div</span></span> <span class="support attribute">class</span><span class="support operator">=</span><span class="string quote">"</span><span class="string value">col</span><span class="string quote">"</span><span class="support tag close">></span>Column 1<span class="support tag"><span class="support tag"><</span><span class="support tag special">/</span><span class="support tag-name">div</span></span><span class="support tag close">></span>
<span class="support tag"><span class="support tag"><</span><span class="support tag-name">div</span></span> <span class="support attribute">class</span><span class="support operator">=</span><span class="string quote">"</span><span class="string value">col</span><span class="string quote">"</span><span class="support tag close">></span>Column 2<span class="support tag"><span class="support tag"><</span><span class="support tag special">/</span><span class="support tag-name">div</span></span><span class="support tag close">></span>
<span class="support tag"><span class="support tag"><</span><span class="support tag-name">div</span></span> <span class="support attribute">class</span><span class="support operator">=</span><span class="string quote">"</span><span class="string value">col</span><span class="string quote">"</span><span class="support tag close">></span>Column 3<span class="support tag"><span class="support tag"><</span><span class="support tag special">/</span><span class="support tag-name">div</span></span><span class="support tag close">></span>
<span class="support tag"><span class="support tag"><</span><span class="support tag special">/</span><span class="support tag-name">div</span></span><span class="support tag close">></span>
<span class="support tag"><span class="support tag"><</span><span class="support tag special">/</span><span class="support tag-name">div</span></span><span class="support tag close">></span>
</code><button class="btn btn-secondary2">Copy</button><div class="preloader"><div></div><div></div><div></div><div></div><div></div><div></div><div></div></div></pre>
Copy to Clipboard Script:
const copyButtonLabel = "Copy";
// use a class selector if available
let blocks = document.querySelectorAll("pre.lang-html");
blocks.forEach((block) => {
// only add button if browser supports Clipboard API
if (navigator.clipboard) {
let button = document.createElement("button");
$(button).addClass( "btn btn-secondary2" );
button.innerText = copyButtonLabel;
block.appendChild(button);
button.addEventListener("click", async () => {
await copyCode(block, button);
});
}
});
async function copyCode(block, button) {
let code = block.querySelector("code");
let text = code.innerText;
await navigator.clipboard.writeText(text);
// visual feedback that task is completed
button.innerText = "Copied";
setTimeout(() => {
button.innerText = copyButtonLabel;
}, 700);
}
For others that run into this same issue: I couldn't find a solution for Rainbow that successfully integrates copy to clipboard. So, I switched to Prism's library instead and the copy functionality above works great!
Here is an article more about it... https://www.roboleary.net/2022/01/13/copy-code-to-clipboard-blog.html