From 23bd7b1211a80aa3b0dcb60ec4a1c0089ff28dd4 Mon Sep 17 00:00:00 2001 From: silverwind Date: Tue, 16 Nov 2021 09:16:05 +0100 Subject: Add copy button to markdown code blocks (#17638) * Add copy button to markdown code blocks Done mostly in JS because I think it's better not to try getting buttons past the markup sanitizer. * add svg module tests * fix sanitizer regexp * remove outdated comment * vertically center button in issue comments as well * add comment to css * fix undefined on view file line copy * combine animation less files * Update modules/markup/markdown/markdown.go Co-authored-by: wxiaoguang * add test for different sizes * add cloneNode and add tests for it * use deep clone * remove useless optional chaining * remove the svg node cache * unify clipboard copy string and i18n * remove unused var * remove unused localization * minor css tweaks to the button * comment tweak * remove useless attribute Co-authored-by: wxiaoguang --- web_src/js/markup/codecopy.js | 16 ++++++++++++++++ web_src/js/markup/content.js | 4 +++- web_src/js/markup/mermaid.js | 5 +++-- 3 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 web_src/js/markup/codecopy.js (limited to 'web_src/js/markup') diff --git a/web_src/js/markup/codecopy.js b/web_src/js/markup/codecopy.js new file mode 100644 index 0000000000..2aa7070c72 --- /dev/null +++ b/web_src/js/markup/codecopy.js @@ -0,0 +1,16 @@ +import {svg} from '../svg.js'; + +export function renderCodeCopy() { + const els = document.querySelectorAll('.markup .code-block code'); + if (!els.length) return; + + const button = document.createElement('button'); + button.classList.add('code-copy', 'ui', 'button'); + button.innerHTML = svg('octicon-copy'); + + for (const el of els) { + const btn = button.cloneNode(true); + btn.setAttribute('data-clipboard-text', el.textContent); + el.after(btn); + } +} diff --git a/web_src/js/markup/content.js b/web_src/js/markup/content.js index 0564199bbf..ef5067fd66 100644 --- a/web_src/js/markup/content.js +++ b/web_src/js/markup/content.js @@ -1,9 +1,11 @@ import {renderMermaid} from './mermaid.js'; +import {renderCodeCopy} from './codecopy.js'; import {initMarkupTasklist} from './tasklist.js'; // code that runs for all markup content export function initMarkupContent() { - const _promise = renderMermaid(document.querySelectorAll('code.language-mermaid')); + renderMermaid(); + renderCodeCopy(); } // code that only runs for comments diff --git a/web_src/js/markup/mermaid.js b/web_src/js/markup/mermaid.js index f9f069ed1e..7c7ee26c3c 100644 --- a/web_src/js/markup/mermaid.js +++ b/web_src/js/markup/mermaid.js @@ -8,8 +8,9 @@ function displayError(el, err) { el.closest('pre').before(errorNode); } -export async function renderMermaid(els) { - if (!els || !els.length) return; +export async function renderMermaid() { + const els = document.querySelectorAll('.markup code.language-mermaid'); + if (!els.length) return; const {default: mermaid} = await import(/* webpackChunkName: "mermaid" */'mermaid'); -- cgit v1.2.3