Website: Add copy button to code blocks in articles, handbook, and osquery table documentation pages (#44778)
Closes: https://github.com/fleetdm/confidential/issues/15273 Changes: - Added a new component `<code-block-copy-buttons>`, a component that adds copy buttons to code blocks on pages it is added to. - Added the new component to the handbook, articles, and osquery table documentation pages Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
Copilot Autofix powered by AI
parent
00d30f28a0
commit
ad3ab6b613
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* <code-block-copy-buttons>
|
||||
* -----------------------------------------------------------------------------
|
||||
* A hovering copy button injected into code blocks that copies the text content when clicked.
|
||||
*
|
||||
* @type {Component}
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
parasails.registerComponent('code-block-copy-buttons', {
|
||||
// ╦ ╦╔╦╗╔╦╗╦
|
||||
// ╠═╣ ║ ║║║║
|
||||
// ╩ ╩ ╩ ╩ ╩╩═╝
|
||||
template: `<span></span>`,
|
||||
|
||||
// ╦ ╦╔═╗╔═╗╔═╗╦ ╦╔═╗╦ ╔═╗
|
||||
// ║ ║╠╣ ║╣ ║ ╚╦╝║ ║ ║╣
|
||||
// ╩═╝╩╚ ╚═╝╚═╝ ╩ ╚═╝╩═╝╚═╝
|
||||
mounted: async function(){
|
||||
// Only add copy buttons if the clipboard method is available.
|
||||
if(typeof navigator.clipboard !== 'undefined' && typeof navigator.clipboard.writeText === 'function'){
|
||||
// Prepend all <pre><code> elements with a code-block-copy-button element, and add the has-copy-button class.
|
||||
$('pre:has(code)').not('.has-copy-button')
|
||||
.prepend('<button type="button" purpose="code-block-copy-button" aria-label="Copy code" title="Copy code"></button>')
|
||||
.addClass('has-copy-button');// Note: we set this bootstrap class to correctly position the copy button without needing to adjust the styles of the page it is added to.
|
||||
|
||||
// Now add click events to each code-block-copy-button element that copies the text content of the neighboring <code> element.
|
||||
$('[purpose="code-block-copy-button"]').on('click', async function() {
|
||||
// Get the text content of the closest <code> element to the copy button.
|
||||
let code = $(this).closest('pre').find('code').text();
|
||||
// Add the copied class to the copy button (which replaces the icon with a checkmark).
|
||||
$(this).addClass('copied');
|
||||
// Remove the copied class after 2 seconds.
|
||||
setTimeout(()=>{
|
||||
$(this).removeClass('copied');
|
||||
}, 2000);
|
||||
navigator.clipboard.writeText(code);
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* <code-block-copy-buttons>
|
||||
*
|
||||
*/
|
||||
|
||||
[purpose='code-block-copy-button'] {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
border-radius: 8px;
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
background: url('/images/icon-copy-16x16@2x.png');
|
||||
background-color: #F9FAFC;
|
||||
background-size: 14px 14px;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
border: none;
|
||||
&.copied {
|
||||
background: url('/images/icon-copy-clicked-checkmark-no-background-32x32@2x.png');
|
||||
background-size: 32px 32px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
border: none;
|
||||
}
|
||||
&:hover {
|
||||
background-color: #E9EEF5;
|
||||
}
|
||||
&:focus {
|
||||
outline: none;
|
||||
background-color: #E9EEF5;
|
||||
}
|
||||
}
|
||||
|
||||
pre.has-copy-button {
|
||||
padding-right: 42px !important;//lesshint-disable-line importantRule
|
||||
position: relative;
|
||||
}
|
||||
|
||||
|
||||
Vendored
+1
@@ -31,6 +31,7 @@
|
||||
@import 'components/docs-nav-and-search.component.less';
|
||||
@import 'components/multifield.component.less';
|
||||
@import 'components/bubble.component.less';
|
||||
@import 'components/code-block-copy-buttons.component.less';
|
||||
|
||||
// Per-page styles
|
||||
@import 'pages/homepage.less';
|
||||
|
||||
Vendored
+1
@@ -883,6 +883,7 @@
|
||||
<script src="/js/components/bubble.component.js"></script>
|
||||
<script src="/js/components/call-to-action.component.js"></script>
|
||||
<script src="/js/components/cloud-error.component.js"></script>
|
||||
<script src="/js/components/code-block-copy-buttons.component.js"></script>
|
||||
<script src="/js/components/docs-nav-and-search.component.js"></script>
|
||||
<script src="/js/components/js-timestamp.component.js"></script>
|
||||
<script src="/js/components/logo-carousel.component.js"></script>
|
||||
|
||||
@@ -139,5 +139,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<code-block-copy-buttons></code-block-copy-buttons>
|
||||
</div>
|
||||
<%- /* Expose server-rendered data as window.SAILS_LOCALS :: */ exposeLocalsToBrowser() %>
|
||||
|
||||
@@ -94,5 +94,6 @@
|
||||
</div>
|
||||
</modal>
|
||||
</div>
|
||||
<code-block-copy-buttons></code-block-copy-buttons>
|
||||
</div>
|
||||
<%- /* Expose server-rendered data as window.SAILS_LOCALS :: */ exposeLocalsToBrowser() %>
|
||||
|
||||
@@ -155,5 +155,6 @@
|
||||
<p class="mb-0"><img alt="An arrow pointing up" class="d-inline" src="/images/icon-arrow-up-12x13@2x.png">Back to top</p>
|
||||
</div>
|
||||
</div>
|
||||
<code-block-copy-buttons></code-block-copy-buttons>
|
||||
</div>
|
||||
<%- /* Expose server-rendered data as window.SAILS_LOCALS :: */ exposeLocalsToBrowser() %>
|
||||
|
||||
Reference in New Issue
Block a user