diff --git a/assets/css/_common/scaffolding/highlight/copy-code.scss b/assets/css/_common/scaffolding/highlight/copy-code.scss
index fc7e19a..bafac01 100644
--- a/assets/css/_common/scaffolding/highlight/copy-code.scss
+++ b/assets/css/_common/scaffolding/highlight/copy-code.scss
@@ -3,7 +3,7 @@
background: var(--highlight-background);
margin-bottom: 26px;
- line-height: 1.185;
+ line-height: 1.25;
//TODO Need fixed the copy button show position.
div:first-child {
diff --git a/assets/js/3rd/others/clipboard.js b/assets/js/3rd/others/clipboard.js
new file mode 100644
index 0000000..8862e2b
--- /dev/null
+++ b/assets/js/3rd/others/clipboard.js
@@ -0,0 +1,37 @@
+/* clipboard plugin */
+NexT.plugins.others.clipboard = function() {
+ const clipboard_js = NexT.utils.getCDNResource(NexT.CONFIG.page.clipboard.js);
+
+ NexT.utils.getScript(clipboard_js, function(){
+
+ let figure = document.querySelectorAll('.highlight pre');
+ if (figure.length === 0 || !NexT.CONFIG.copybtn) return;
+ figure.forEach(element => {
+ let cn = element.querySelector('code').className;
+ if (cn === '') return;
+ element.children[0].insertAdjacentHTML('beforebegin', '
');
+ var clipboard = new ClipboardJS(element.children[0],
+ {
+ text: function(trigger) {
+ return trigger.nextElementSibling.textContent.trim();
+ }
+ });
+ clipboard.on('success', function (e) {
+ e.clearSelection();
+ button.querySelector('i').className = 'fa fa-check-circle fa-fw';
+ });
+
+ clipboard.on('error', function (e) {
+ console.error('Copy failed:', e);
+ button.querySelector('i').className = 'fa fa-times-circle fa-fw';
+ });
+
+ const button = element.querySelector('.copy-btn');
+ element.addEventListener('mouseleave', () => {
+ setTimeout(() => {
+ button.querySelector('i').className = 'fa fa-copy fa-fw';
+ }, 300);
+ });
+ });
+ });
+}
\ No newline at end of file
diff --git a/assets/js/next-boot.js b/assets/js/next-boot.js
index 0e5104a..b6c3ed2 100644
--- a/assets/js/next-boot.js
+++ b/assets/js/next-boot.js
@@ -67,7 +67,6 @@ NexT.boot.refresh = function() {
if (NexT.CONFIG.page.expired) NexT.utils.calPostExpiredDate();
if (NexT.CONFIG.page.music) NexT.utils.registerAPlayer();
- NexT.utils.registerCopyCode();
NexT.utils.registerImageViewer();
NexT.utils.registerPostReward();
diff --git a/assets/js/utils.js b/assets/js/utils.js
index a8c0778..1050fca 100644
--- a/assets/js/utils.js
+++ b/assets/js/utils.js
@@ -306,27 +306,57 @@ NexT.utils = {
registerCopyCode: function () {
if (!NexT.CONFIG.copybtn) return;
- let figure = document.querySelectorAll('.highlight pre');
+ /** let figure = document.querySelectorAll('.highlight pre');
if (figure.length === 0 || !NexT.CONFIG.copybtn) return;
figure.forEach(element => {
- let cn = element.querySelector('code').className;
- // TODO seems hard code need find other ways fixed it.
- if (cn == '') return;
- element.insertAdjacentHTML('beforeend', '
');
+ let cn = element.querySelector('code').className;
+ if (cn === '') return;
+ element.children[0].insertAdjacentHTML('beforebegin', '
');
+ var clipboard = new ClipboardJS(element.children[0],
+ {
+ text: function(trigger) {
+ return trigger.nextElementSibling.textContent.trim();
+ }
+ });
+ clipboard.on('success', function (e) {
+ e.clearSelection();
+ console.info('Action:', e.action);
+ console.info('Text:', e.text);
+ button.querySelector('i').className = 'fa fa-check-circle fa-fw';
+ });
+ clipboard.on('error', function (e) {
+ console.error('复制失败:', e);
+ button.querySelector('i').className = 'fa fa-times-circle fa-fw';
+ });
const button = element.querySelector('.copy-btn');
- button.addEventListener('click', () => {
+ element.addEventListener('mouseleave', () => {
+ setTimeout(() => {
+ button.querySelector('i').className = 'fa fa-copy fa-fw';
+ }, 300);
+ });
+ });**/
+ /** figure.forEach(element => {
+ let cn = element.querySelector('code').className;
+ if (cn === '') return;
+ element.insertAdjacentHTML('beforeend', '
');
+ // element.insertAdjacentHTML('beforeend', '
');
+ const button = element.querySelector('.copy-btn');
+ button.addEventListener('click', async () => {
const lines = element.querySelector('.code') || element.querySelector('code');
- const code = lines.innerText.replace(/(\n{2,})/g, '\n');
+ let code = lines.textContent.trim();
+ console.log('尝试复制代码:', code);
+
if (navigator.clipboard) {
- // https://caniuse.com/mdn-api_clipboard_writetext
navigator.clipboard.writeText(code).then(() => {
+ console.log('复制成功');
button.querySelector('i').className = 'fa fa-check-circle fa-fw';
- }, () => {
+ }).catch((err) => {
+ console.error('复制失败:', err);
button.querySelector('i').className = 'fa fa-times-circle fa-fw';
});
} else {
const ta = document.createElement('textarea');
- ta.style.top = window.scrollY + 'px'; // Prevent page scrolling
+ ta.style.top = window.scrollY + 'px';
ta.style.position = 'absolute';
ta.style.opacity = '0';
ta.readOnly = true;
@@ -334,20 +364,22 @@ NexT.utils = {
document.body.append(ta);
ta.select();
ta.setSelectionRange(0, code.length);
- ta.readOnly = false;
- const result = document.execCommand('copy');
- button.querySelector('i').className = result ? 'fa fa-check-circle fa-fw' : 'fa fa-times-circle fa-fw';
- ta.blur(); // For iOS
- button.blur();
+ try {
+ const successful = document.execCommand('copy');
+ if (!successful) throw new Error('复制命令执行失败');
+ } catch (err) {
+ console.error('复制失败:', err);
+ }
document.body.removeChild(ta);
}
+
});
element.addEventListener('mouseleave', () => {
setTimeout(() => {
button.querySelector('i').className = 'fa fa-copy fa-fw';
}, 300);
});
- });
+ });**/
},
wrapTableWithBox: function () {
diff --git a/data/resources.yaml b/data/resources.yaml
index a8ad1cd..5c6eabd 100644
--- a/data/resources.yaml
+++ b/data/resources.yaml
@@ -145,6 +145,7 @@ utterances:
livere:
js: https://cdn-city.livere.com/js/embed.dist.js
+
# 全文搜索
# Full text search
algolia:
@@ -231,4 +232,10 @@ plugins:
css:
name: aplayer
version: 1.10.1
- file: dist/APlayer.min.css
\ No newline at end of file
+ file: dist/APlayer.min.css
+ # 复制到剪贴板
+ clipboard:
+ js:
+ name: clipboard
+ version: 2.0.11
+ file: dist/clipboard.min.js
\ No newline at end of file
diff --git a/exampleSite/content/post/hugo-blockquote.md b/exampleSite/content/post/hugo-blockquote.md
index 6c1b1ec..cc1ee62 100644
--- a/exampleSite/content/post/hugo-blockquote.md
+++ b/exampleSite/content/post/hugo-blockquote.md
@@ -27,9 +27,7 @@ expired: true
用户可以找到如下两处配置项的位置,然后根据自己喜欢的风格和颜色进行调整:
```yaml
-
# config.yaml 或 hugo.toml
-
postAlerts:
info:
icon: "circle-info"
@@ -56,7 +54,6 @@ postAlerts:
```yaml
# i18n/zh-cn.yaml
-
PostAlert:
info : "信息"
note : "注意"
diff --git a/layouts/_default/_markup/render-codeblock.html b/layouts/_default/_markup/render-codeblock.html
new file mode 100644
index 0000000..5e27219
--- /dev/null
+++ b/layouts/_default/_markup/render-codeblock.html
@@ -0,0 +1,4 @@
+{{ $result := transform.HighlightCodeBlock . }}
+{{ $result.Wrapped }}
+
+{{ .Page.Store.Set "codeblock" true }}
\ No newline at end of file
diff --git a/layouts/partials/head/config.html b/layouts/partials/head/config.html
index 09ba67b..8bf3a27 100644
--- a/layouts/partials/head/config.html
+++ b/layouts/partials/head/config.html
@@ -12,6 +12,14 @@
"title" .Page.Title
}}
+{{/** Append clipboard plugin */}}
+{{ if .Store.Get "codeblock" }}
+{{ $clipboard := dict
+ "js" $.Site.Data.resources.plugins.clipboard.js
+}}
+{{ $pageCfg = merge $pageCfg (dict "clipboard" $clipboard) }}
+{{ end }}
+
{{/** Append APlayer plugin */}}
{{ if $scParam.music }}
{{ $aplayer := dict
diff --git a/layouts/partials/head/script/plugins.html b/layouts/partials/head/script/plugins.html
index 184b90d..d2d38d1 100644
--- a/layouts/partials/head/script/plugins.html
+++ b/layouts/partials/head/script/plugins.html
@@ -1,6 +1,11 @@
{{/* Defind loading plugin scripts which only need in pages */}}
{{ if .IsPage }}
+{{/** Append codeblack render action **/}}
+{{ if .Store.Get "codeblock" }}
+ {{ partial "_funs/get_plugin.html" (dict "ctx" . "class" "others" "plugin" "clipboard.js") }}
+{{ end }}
+
{{/** Short code params **/}}
{{ $scParam := .Store.Get "scParams" }}
diff --git a/static/js/3rd/clipboard/2.0.11/clipboard.min.js b/static/js/3rd/clipboard/2.0.11/clipboard.min.js
new file mode 100644
index 0000000..9f97edb
--- /dev/null
+++ b/static/js/3rd/clipboard/2.0.11/clipboard.min.js
@@ -0,0 +1,7 @@
+/*!
+ * clipboard.js v2.0.11
+ * https://clipboardjs.com/
+ *
+ * Licensed MIT © Zeno Rocha
+ */
+!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={686:function(t,e,n){"use strict";n.d(e,{default:function(){return b}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),r=n.n(e);function c(t){try{return document.execCommand(t)}catch(t){return}}var a=function(t){t=r()(t);return c("cut"),t};function o(t,e){var n,o,t=(n=t,o="rtl"===document.documentElement.getAttribute("dir"),(t=document.createElement("textarea")).style.fontSize="12pt",t.style.border="0",t.style.padding="0",t.style.margin="0",t.style.position="absolute",t.style[o?"right":"left"]="-9999px",o=window.pageYOffset||document.documentElement.scrollTop,t.style.top="".concat(o,"px"),t.setAttribute("readonly",""),t.value=n,t);return e.container.appendChild(t),e=r()(t),c("copy"),t.remove(),e}var f=function(t){var e=1