[opt] copycode

This commit is contained in:
xaoxuu 2023-05-09 12:54:34 +08:00
parent 72666f39d8
commit 53bbd972a6
8 changed files with 94 additions and 93 deletions

View File

@ -78,12 +78,6 @@ TianliGpt:
wiki: true
api: 5Q5mpqRK5DkwT1X9Gi5e
# 代码块
CodeBlock:
show_copy: true
default_text: 'copy'
success_text: 'copied'
search:
service: local_search # local_search, todo...
local_search: # 在 front-matter 中设置 indexing:false 来避免被搜索索引
@ -366,6 +360,13 @@ plugins:
# 推荐使用 dark 主题 在夜间模式下显示效果更好
theme: dark
# 代码块复制按钮
copycode:
enable: true
js: /js/plugins/copycode.js
default_text: 'Copy'
success_text: 'Copied'
style:
darkmode: auto # auto / always / false
smooth_scroll: true # true / false

View File

@ -1,86 +0,0 @@
<% if (theme.CodeBlock.show_copy) { %>
<style>
.highlight {
position: relative;
}
.highlight .code .copy-btn{
position: absolute;
top: 0;
right: 0;
padding: 4px 0.5rem;
opacity: 0.25;
font-weight: 700;
color: var(--theme);
cursor: pointer;
transition: opacity 0.3s;
}
.highlight .code .copy-btn:hover{
color: var(--text-code);
opacity: 0.75;
}
.highlight .code .copy-btn.success {
color: var(--swiper-theme-color);
opacity: 0.75;
}
.highlight .code .copy-btn.warning {
color: var(--text-code);
opacity: 0.75;
}
</style>
<script>
const codeElementArr = document.querySelectorAll('.code')
codeElementArr.forEach(code => {
const codeBeforeWidth = window.getComputedStyle(code, '::before').width.split('px')[0]
const codeBeforePadding = window.getComputedStyle(code, '::before').padding.split(' ').pop().split('px')[0]
// copy btn
const codeCopyBtn = document.createElement('div')
codeCopyBtn.classList.add('copy-btn')
codeCopyBtn.style.right = Number(codeBeforeWidth) + Number(codeBeforePadding) * 2 + 'px'
codeCopyBtn.innerText = '<%= theme.CodeBlock.default_text%>'
code.appendChild(codeCopyBtn)
codeCopyBtn.addEventListener('click', async () => {
const currentCodeElement = code.children[0]?.innerText
await copyCode(currentCodeElement)
codeCopyBtn.innerText = '<%= theme.CodeBlock.success_text%>'
codeCopyBtn.classList.add('success')
setTimeout(() => {
codeCopyBtn.innerText = '<%= theme.CodeBlock.default_text%>'
codeCopyBtn.classList.remove('success')
},1000)
})
})
async function copyCode(currentCode) {
// console.log(currentCode)
// console.log('复制代码')
if (navigator.clipboard) {
try {
await navigator.clipboard.writeText(currentCode)
} catch (error) {
// 未获得用户许可
codeCopyBtn.innerText = '未获得用户许可'
codeCopyBtn.classList.add('warning')
setTimeout(() => {
codeCopyBtn.innerText = '<%= theme.CodeBlock.default_text%>'
codeCopyBtn.classList.remove('warning')
},1000)
}
} else {
codeCopyBtn.innerText = '当前浏览器不支持此api'
codeCopyBtn.classList.add('warning')
setTimeout(() => {
codeCopyBtn.innerText = '<%= theme.CodeBlock.default_text%>'
codeCopyBtn.classList.remove('warning')
},1000)
}
}
</script>
<% } %>

View File

@ -143,6 +143,9 @@
if ('<%- theme.plugins.heti.enable %>' == 'true') {
stellar.plugins.heti = Object.assign(<%- JSON.stringify(theme.plugins.heti) %>);
}
if ('<%- theme.plugins.copycode.enable %>' == 'true') {
stellar.plugins.copycode = Object.assign(<%- JSON.stringify(theme.plugins.copycode) %>);
}
</script>
<!-- required -->

View File

@ -16,7 +16,6 @@
</div>
<div class='scripts'>
<%- partial('_partial/scripts/index') %>
<%- partial('_partial/main/copycode') %>
</div>
</body>
</html>

View File

@ -0,0 +1,27 @@
.highlight
position: relative
.highlight .code .copy-btn
position: absolute
top: 0
right: 0
padding: 4px 0.5rem
opacity: 0
font-weight: 700
color: var(--theme)
cursor: pointer
.highlight:hover .copy-btn
opacity 0.25
.highlight .code .copy-btn:hover
color: var(--theme)
opacity: 0.75
.highlight .code .copy-btn.success
color: $c-green
opacity: 0.75
.highlight .code .copy-btn.warning
color: $c-orange
opacity: 0.75

View File

@ -11,6 +11,8 @@ if hexo-config('plugins.fancybox.enable')
@import 'fancybox'
if hexo-config('plugins.mermaid.enable')
@import 'mermaid'
if hexo-config('plugins.copycode.enable')
@import 'copycode'
//

View File

@ -385,3 +385,7 @@ if (stellar.plugins.heti) {
stellar.plugins.heti.enable = false;
});
}
if (stellar.plugins.copycode) {
stellar.loadScript(stellar.plugins.copycode.js, { defer: true })
}

View File

@ -0,0 +1,51 @@
const codeElementArr = document.querySelectorAll('.code')
codeElementArr.forEach(code => {
const codeBeforeWidth = window.getComputedStyle(code, '::before').width.split('px')[0]
const codeBeforePadding = window.getComputedStyle(code, '::before').padding.split(' ').pop().split('px')[0]
// copy btn
const codeCopyBtn = document.createElement('div')
codeCopyBtn.classList.add('copy-btn')
codeCopyBtn.style.right = Number(codeBeforeWidth) + Number(codeBeforePadding) * 2 + 'px'
codeCopyBtn.innerText = stellar.plugins.copycode.default_text
code.appendChild(codeCopyBtn)
codeCopyBtn.addEventListener('click', async () => {
const currentCodeElement = code.children[0]?.innerText
await copyCode(currentCodeElement)
codeCopyBtn.innerText = stellar.plugins.copycode.success_text
codeCopyBtn.classList.add('success')
setTimeout(() => {
codeCopyBtn.innerText = stellar.plugins.copycode.default_text
codeCopyBtn.classList.remove('success')
},3000)
})
})
async function copyCode(currentCode) {
// console.log(currentCode)
// console.log('复制代码')
if (navigator.clipboard) {
try {
await navigator.clipboard.writeText(currentCode)
} catch (error) {
// 未获得用户许可
codeCopyBtn.innerText = '未获得用户许可'
codeCopyBtn.classList.add('warning')
setTimeout(() => {
codeCopyBtn.innerText = stellar.plugins.copycode.default_text
codeCopyBtn.classList.remove('warning')
},3000)
}
} else {
codeCopyBtn.innerText = '当前浏览器不支持此api'
codeCopyBtn.classList.add('warning')
setTimeout(() => {
codeCopyBtn.innerText = stellar.plugins.copycode.default_text
codeCopyBtn.classList.remove('warning')
},3000)
}
}