提交 06d546b7 编写于 作者: G Geri Ochoa 提交者: tekton-robot

Implement click-to-copy for code listings

Implement click-to-copy for code blocks. Code blocks with no syntax
highlight won't show the button

Additional changes:

- Bump up Popper and Bootstrap versions
- Move script-importing code from header to the scripts partial
上级 7c204954
let codeListings = document.querySelectorAll('.highlight > pre');
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 buttonTooltip = document.createElement('div');
buttonTooltip.classList.add('c2c-tooltip');
buttonTooltip.setAttribute('role', 'tooltip');
buttonTooltip.innerHTML += 'Copy to clipboard';
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());
}
......@@ -37,3 +37,61 @@
&.navbar-bg-onscroll { background: $dark !important }
}
/* Click-to-copy button styles */
.highlight {
position: relative;
.click-to-copy {
display: block;
text-align: right;
height: 1ex;
}
pre {
button {
position: absolute;
color: $light;
border-radius: 3px;
border-width: 0;
background-color: inherit;
box-shadow: 1px 1px $light;
right: 8px;
top: 6px;
}
button:hover {
color: $dark;
background-color: $light;
}
button:active {
color: $dark;
background-color: $light;
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.7s linear;
}
.c2c-tooltip[show-tooltip] {
visibility: visible;
opacity: 1;
}
}
}
/* Consistent borders around code blocks */
pre { border: 1px solid $light;}
......@@ -19,8 +19,4 @@
{{ template "_internal/google_analytics_async.html" . }}
{{ end }}
{{ partialCached "head-css.html" . "asdf" }}
<script
src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script>
{{ partial "hooks/head-end.html" . }}
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
<script src="https://code.jquery.com/jquery-3.6.1.min.js"
integrity="sha256-o88AwQnZB+VDvE9tvIXrMQaPlFFSUTR+nldQm1LuPXQ="
crossorigin="anonymous"></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/2.9.2/umd/popper.min.js"
integrity="sha512-2rNj2KJ+D8s1ceNasTIex6z4HWyOnEYLVC3FigGOmyQCZc2eBXKgOxQmo3oKLHyfcj53uz4QMsRCWNbLd32Q1g=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
{{ $jsBase := resources.Get "js/base.js" }}
{{ $jsSearch := resources.Get "js/search.js" | resources.ExecuteAsTemplate "js/search.js" .Site.Home }}
......@@ -10,4 +16,8 @@
{{ $js := $js | minify | fingerprint }}
<script src="{{ $js.RelPermalink }}" integrity="{{ $js.Data.Integrity }}"></script>
{{ end }}
{{ $c2cJS := resources.Get "js/click-to-copy.js" | minify | fingerprint }}
<script defer src="{{ $c2cJS.Permalink }}" integrity="{{ $c2cJS.Data.Integrity }}"></script>
{{ partial "hooks/body-end.html" . }}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册