🐛 Fxied #139, make render code block & clipboard remove last enter line.
This commit is contained in:
parent
e9297ac28b
commit
23e220b5f3
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
background: var(--highlight-background);
|
background: var(--highlight-background);
|
||||||
margin-bottom: 26px;
|
margin-bottom: 26px;
|
||||||
line-height: 1.185;
|
line-height: 1.25;
|
||||||
|
|
||||||
//TODO Need fixed the copy button show position.
|
//TODO Need fixed the copy button show position.
|
||||||
div:first-child {
|
div:first-child {
|
||||||
|
37
assets/js/3rd/others/clipboard.js
Normal file
37
assets/js/3rd/others/clipboard.js
Normal file
@ -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', '<div class="copy-btn" data-clipboard-snippe><i class="fa fa-copy fa-fw"></i></div>');
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
@ -67,7 +67,6 @@ NexT.boot.refresh = function() {
|
|||||||
if (NexT.CONFIG.page.expired) NexT.utils.calPostExpiredDate();
|
if (NexT.CONFIG.page.expired) NexT.utils.calPostExpiredDate();
|
||||||
if (NexT.CONFIG.page.music) NexT.utils.registerAPlayer();
|
if (NexT.CONFIG.page.music) NexT.utils.registerAPlayer();
|
||||||
|
|
||||||
NexT.utils.registerCopyCode();
|
|
||||||
NexT.utils.registerImageViewer();
|
NexT.utils.registerImageViewer();
|
||||||
NexT.utils.registerPostReward();
|
NexT.utils.registerPostReward();
|
||||||
|
|
||||||
|
@ -306,27 +306,57 @@ NexT.utils = {
|
|||||||
registerCopyCode: function () {
|
registerCopyCode: function () {
|
||||||
if (!NexT.CONFIG.copybtn) return;
|
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;
|
if (figure.length === 0 || !NexT.CONFIG.copybtn) return;
|
||||||
figure.forEach(element => {
|
figure.forEach(element => {
|
||||||
let cn = element.querySelector('code').className;
|
let cn = element.querySelector('code').className;
|
||||||
// TODO seems hard code need find other ways fixed it.
|
if (cn === '') return;
|
||||||
if (cn == '') return;
|
element.children[0].insertAdjacentHTML('beforebegin', '<div class="copy-btn" data-clipboard-snippe><i class="fa fa-copy fa-fw"></i></div>');
|
||||||
element.insertAdjacentHTML('beforeend', '<div class="copy-btn"><i class="fa fa-copy fa-fw"></i></div>');
|
var clipboard = new ClipboardJS(element.children[0],
|
||||||
const button = element.querySelector('.copy-btn');
|
{
|
||||||
button.addEventListener('click', () => {
|
text: function(trigger) {
|
||||||
const lines = element.querySelector('.code') || element.querySelector('code');
|
return trigger.nextElementSibling.textContent.trim();
|
||||||
const code = lines.innerText.replace(/(\n{2,})/g, '\n');
|
}
|
||||||
if (navigator.clipboard) {
|
});
|
||||||
// https://caniuse.com/mdn-api_clipboard_writetext
|
clipboard.on('success', function (e) {
|
||||||
navigator.clipboard.writeText(code).then(() => {
|
e.clearSelection();
|
||||||
|
console.info('Action:', e.action);
|
||||||
|
console.info('Text:', e.text);
|
||||||
button.querySelector('i').className = 'fa fa-check-circle fa-fw';
|
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');
|
||||||
|
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', '<div class="copy-btn"><i class="fa fa-copy fa-fw"></i></div>');
|
||||||
|
// element.insertAdjacentHTML('beforeend', '<div class="copy-btn"><i class="fa fa-copy fa-fw"></i></div>');
|
||||||
|
const button = element.querySelector('.copy-btn');
|
||||||
|
button.addEventListener('click', async () => {
|
||||||
|
const lines = element.querySelector('.code') || element.querySelector('code');
|
||||||
|
let code = lines.textContent.trim();
|
||||||
|
console.log('尝试复制代码:', code);
|
||||||
|
|
||||||
|
if (navigator.clipboard) {
|
||||||
|
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';
|
button.querySelector('i').className = 'fa fa-times-circle fa-fw';
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const ta = document.createElement('textarea');
|
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.position = 'absolute';
|
||||||
ta.style.opacity = '0';
|
ta.style.opacity = '0';
|
||||||
ta.readOnly = true;
|
ta.readOnly = true;
|
||||||
@ -334,20 +364,22 @@ NexT.utils = {
|
|||||||
document.body.append(ta);
|
document.body.append(ta);
|
||||||
ta.select();
|
ta.select();
|
||||||
ta.setSelectionRange(0, code.length);
|
ta.setSelectionRange(0, code.length);
|
||||||
ta.readOnly = false;
|
try {
|
||||||
const result = document.execCommand('copy');
|
const successful = document.execCommand('copy');
|
||||||
button.querySelector('i').className = result ? 'fa fa-check-circle fa-fw' : 'fa fa-times-circle fa-fw';
|
if (!successful) throw new Error('复制命令执行失败');
|
||||||
ta.blur(); // For iOS
|
} catch (err) {
|
||||||
button.blur();
|
console.error('复制失败:', err);
|
||||||
|
}
|
||||||
document.body.removeChild(ta);
|
document.body.removeChild(ta);
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
element.addEventListener('mouseleave', () => {
|
element.addEventListener('mouseleave', () => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
button.querySelector('i').className = 'fa fa-copy fa-fw';
|
button.querySelector('i').className = 'fa fa-copy fa-fw';
|
||||||
}, 300);
|
}, 300);
|
||||||
});
|
});
|
||||||
});
|
});**/
|
||||||
},
|
},
|
||||||
|
|
||||||
wrapTableWithBox: function () {
|
wrapTableWithBox: function () {
|
||||||
|
@ -145,6 +145,7 @@ utterances:
|
|||||||
livere:
|
livere:
|
||||||
js: https://cdn-city.livere.com/js/embed.dist.js
|
js: https://cdn-city.livere.com/js/embed.dist.js
|
||||||
|
|
||||||
|
|
||||||
# 全文搜索
|
# 全文搜索
|
||||||
# Full text search
|
# Full text search
|
||||||
algolia:
|
algolia:
|
||||||
@ -232,3 +233,9 @@ plugins:
|
|||||||
name: aplayer
|
name: aplayer
|
||||||
version: 1.10.1
|
version: 1.10.1
|
||||||
file: dist/APlayer.min.css
|
file: dist/APlayer.min.css
|
||||||
|
# 复制到剪贴板
|
||||||
|
clipboard:
|
||||||
|
js:
|
||||||
|
name: clipboard
|
||||||
|
version: 2.0.11
|
||||||
|
file: dist/clipboard.min.js
|
@ -27,9 +27,7 @@ expired: true
|
|||||||
用户可以找到如下两处配置项的位置,然后根据自己喜欢的风格和颜色进行调整:
|
用户可以找到如下两处配置项的位置,然后根据自己喜欢的风格和颜色进行调整:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
|
|
||||||
# config.yaml 或 hugo.toml
|
# config.yaml 或 hugo.toml
|
||||||
|
|
||||||
postAlerts:
|
postAlerts:
|
||||||
info:
|
info:
|
||||||
icon: "circle-info"
|
icon: "circle-info"
|
||||||
@ -56,7 +54,6 @@ postAlerts:
|
|||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
# i18n/zh-cn.yaml
|
# i18n/zh-cn.yaml
|
||||||
|
|
||||||
PostAlert:
|
PostAlert:
|
||||||
info : "信息"
|
info : "信息"
|
||||||
note : "注意"
|
note : "注意"
|
||||||
|
4
layouts/_default/_markup/render-codeblock.html
Normal file
4
layouts/_default/_markup/render-codeblock.html
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{{ $result := transform.HighlightCodeBlock . }}
|
||||||
|
{{ $result.Wrapped }}
|
||||||
|
|
||||||
|
{{ .Page.Store.Set "codeblock" true }}
|
@ -12,6 +12,14 @@
|
|||||||
"title" .Page.Title
|
"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 */}}
|
{{/** Append APlayer plugin */}}
|
||||||
{{ if $scParam.music }}
|
{{ if $scParam.music }}
|
||||||
{{ $aplayer := dict
|
{{ $aplayer := dict
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
{{/* Defind loading plugin scripts which only need in pages */}}
|
{{/* Defind loading plugin scripts which only need in pages */}}
|
||||||
{{ if .IsPage }}
|
{{ 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 **/}}
|
{{/** Short code params **/}}
|
||||||
{{ $scParam := .Store.Get "scParams" }}
|
{{ $scParam := .Store.Get "scParams" }}
|
||||||
|
|
||||||
|
7
static/js/3rd/clipboard/2.0.11/clipboard.min.js
vendored
Normal file
7
static/js/3rd/clipboard/2.0.11/clipboard.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user