From 743d55fa49460bfc98f1a79e1a16427c6595d7b1 Mon Sep 17 00:00:00 2001 From: Chen Xianmin Date: Wed, 2 Oct 2024 11:35:55 +0800 Subject: [PATCH] feat: add copy-code-btn #360 --- assets/js/initCopyCode.js | 26 ++++++++++ assets/js/main.js | 4 +- .../_partial/_post/_content/_highlight.scss | 36 ------------- assets/sass/_shortcodes/_highlight.scss | 50 +++++++++++++++++++ assets/sass/jane.scss | 2 +- .../_default/_markup/render-codeblock.html | 7 +++ layouts/shortcodes/highlight.html | 8 +++ 7 files changed, 95 insertions(+), 38 deletions(-) create mode 100644 assets/js/initCopyCode.js delete mode 100644 assets/sass/_partial/_post/_content/_highlight.scss create mode 100644 assets/sass/_shortcodes/_highlight.scss create mode 100644 layouts/_default/_markup/render-codeblock.html create mode 100644 layouts/shortcodes/highlight.html diff --git a/assets/js/initCopyCode.js b/assets/js/initCopyCode.js new file mode 100644 index 00000000..12228f98 --- /dev/null +++ b/assets/js/initCopyCode.js @@ -0,0 +1,26 @@ +const initCopyCode = () => { + const containers = document.querySelectorAll('.highlight-container'); + + containers.forEach(container => { + const copyBtn = container.querySelector('.copy-code-btn'); + const codeElement = container.querySelector('.highlight code[data-lang]'); + + copyBtn.addEventListener('click', function () { + navigator.clipboard.writeText(codeElement.textContent).then(function () { + /* Chrome doesn't seem to blur automatically, + leaving the button in a focused state. */ + copyBtn.blur(); + + copyBtn.innerText = 'Copied!'; + + setTimeout(function () { + copyBtn.innerText = 'Copy'; + }, 2000); + }, function (error) { + copyBtn.innerText = 'Error'; + }); + }); + }) +} + +export default initCopyCode; diff --git a/assets/js/main.js b/assets/js/main.js index 147270b3..5efc145a 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -2,6 +2,7 @@ import initMobileNavbar from './initMobileNavbar.js'; import initToc from './initToc.js'; import initHeaderAnchor from './initHeaderAnchor.js'; import initToggleTheme from './initToggleTheme.js'; +import initCopyCode from './initCopyCode.js'; // Use an async function to handle asynchronous initialization async function initApp() { @@ -13,7 +14,8 @@ async function initApp() { await Promise.all([ initMobileNavbar(), initToc(), - initHeaderAnchor() + initHeaderAnchor(), + initCopyCode() ]); console.log('All modules initialized successfully'); diff --git a/assets/sass/_partial/_post/_content/_highlight.scss b/assets/sass/_partial/_post/_content/_highlight.scss deleted file mode 100644 index f1c2f03d..00000000 --- a/assets/sass/_partial/_post/_content/_highlight.scss +++ /dev/null @@ -1,36 +0,0 @@ -.highlight { - position: relative; - margin: 1em 0; - overflow-x: auto; - border: 2px solid #dddddd; - line-height: 1.6; - - & > div { - padding: 1em 0.3em; - } - - code { - all: unset; - border-radius: 0; - padding: 0 !important; - } - - pre { - margin: 0; /* remove normal pre margin */ - border-radius: 0; - } - - table { - padding: 1em 0.3em !important; - - td:nth-child(2) code { - &::after { - position: absolute; - top: 0; - right: 0.5em; - font-weight: bold; - content: attr(data-lang); - } - } - } -} diff --git a/assets/sass/_shortcodes/_highlight.scss b/assets/sass/_shortcodes/_highlight.scss new file mode 100644 index 00000000..ed69ed1a --- /dev/null +++ b/assets/sass/_shortcodes/_highlight.scss @@ -0,0 +1,50 @@ +.highlight-container { + margin: 1em 0; +} + +.highlight { + position: relative; + overflow-x: auto; + border: 2px solid #dddddd; + line-height: 1.6; + + & > div { + padding: 1em 0.3em; + } + + code { + all: unset; + border-radius: 0; + padding: 0 !important; + } + + pre { + margin: 0; /* remove normal pre margin */ + border-radius: 0; + } + + table { + padding: 1em 0.3em !important; + + // td:nth-child(2) code { + // &::after { + // position: absolute; + // top: 0; + // left: 0.5em; + // font-weight: bold; + // content: attr(data-lang); + // } + // } + } +} + +button.copy-code-btn { + /* right-align */ + display: block; + margin-left: auto; + margin-right: 0; + + margin-bottom: -2px; + font-size: 0.6em; + padding: 0.1em 0.3em; +} diff --git a/assets/sass/jane.scss b/assets/sass/jane.scss index 9a4f77fc..cb688f7f 100644 --- a/assets/sass/jane.scss +++ b/assets/sass/jane.scss @@ -190,7 +190,6 @@ $mobile-breakpoint: 768px !default; // @import "_partial/404"; // @import "_partial/author_info"; // @import "_partial/search"; -@import "_partial/_post/_content/highlight"; // global highlight style /**------------------------------------------------------------------------ * page styles @@ -207,6 +206,7 @@ $mobile-breakpoint: 768px !default; /**------------------------------------------------------------------------ * shortcodes *------------------------------------------------------------------------**/ +@import "_shortcodes/highlight"; @import "_shortcodes/notice"; /**------------------------------------------------------------------------ diff --git a/layouts/_default/_markup/render-codeblock.html b/layouts/_default/_markup/render-codeblock.html new file mode 100644 index 00000000..554e175b --- /dev/null +++ b/layouts/_default/_markup/render-codeblock.html @@ -0,0 +1,7 @@ +
+ + + + {{ $result := transform.HighlightCodeBlock . }} + {{ $result.Wrapped }} +
diff --git a/layouts/shortcodes/highlight.html b/layouts/shortcodes/highlight.html new file mode 100644 index 00000000..67b7bd79 --- /dev/null +++ b/layouts/shortcodes/highlight.html @@ -0,0 +1,8 @@ +
+ + {{- if len .Params | eq 2 }} + {{ highlight (trim .InnerDeindent "\n\r") (.Get 0) (.Get 1) }} + {{- else }} + {{ highlight (trim .InnerDeindent "\n\r") (.Get 0) "" }} + {{- end }} +