[opt] copycode
This commit is contained in:
parent
72666f39d8
commit
53bbd972a6
13
_config.yml
13
_config.yml
|
@ -78,12 +78,6 @@ TianliGpt:
|
||||||
wiki: true
|
wiki: true
|
||||||
api: 5Q5mpqRK5DkwT1X9Gi5e
|
api: 5Q5mpqRK5DkwT1X9Gi5e
|
||||||
|
|
||||||
# 代码块
|
|
||||||
CodeBlock:
|
|
||||||
show_copy: true
|
|
||||||
default_text: 'copy'
|
|
||||||
success_text: 'copied'
|
|
||||||
|
|
||||||
search:
|
search:
|
||||||
service: local_search # local_search, todo...
|
service: local_search # local_search, todo...
|
||||||
local_search: # 在 front-matter 中设置 indexing:false 来避免被搜索索引
|
local_search: # 在 front-matter 中设置 indexing:false 来避免被搜索索引
|
||||||
|
@ -366,6 +360,13 @@ plugins:
|
||||||
# 推荐使用 dark 主题 在夜间模式下显示效果更好
|
# 推荐使用 dark 主题 在夜间模式下显示效果更好
|
||||||
theme: dark
|
theme: dark
|
||||||
|
|
||||||
|
# 代码块复制按钮
|
||||||
|
copycode:
|
||||||
|
enable: true
|
||||||
|
js: /js/plugins/copycode.js
|
||||||
|
default_text: 'Copy'
|
||||||
|
success_text: 'Copied'
|
||||||
|
|
||||||
style:
|
style:
|
||||||
darkmode: auto # auto / always / false
|
darkmode: auto # auto / always / false
|
||||||
smooth_scroll: true # true / false
|
smooth_scroll: true # true / false
|
||||||
|
|
|
@ -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>
|
|
||||||
<% } %>
|
|
||||||
|
|
|
@ -143,6 +143,9 @@
|
||||||
if ('<%- theme.plugins.heti.enable %>' == 'true') {
|
if ('<%- theme.plugins.heti.enable %>' == 'true') {
|
||||||
stellar.plugins.heti = Object.assign(<%- JSON.stringify(theme.plugins.heti) %>);
|
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>
|
</script>
|
||||||
|
|
||||||
<!-- required -->
|
<!-- required -->
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
</div>
|
</div>
|
||||||
<div class='scripts'>
|
<div class='scripts'>
|
||||||
<%- partial('_partial/scripts/index') %>
|
<%- partial('_partial/scripts/index') %>
|
||||||
<%- partial('_partial/main/copycode') %>
|
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -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
|
|
@ -11,6 +11,8 @@ if hexo-config('plugins.fancybox.enable')
|
||||||
@import 'fancybox'
|
@import 'fancybox'
|
||||||
if hexo-config('plugins.mermaid.enable')
|
if hexo-config('plugins.mermaid.enable')
|
||||||
@import 'mermaid'
|
@import 'mermaid'
|
||||||
|
if hexo-config('plugins.copycode.enable')
|
||||||
|
@import 'copycode'
|
||||||
|
|
||||||
|
|
||||||
// 评论
|
// 评论
|
||||||
|
|
|
@ -385,3 +385,7 @@ if (stellar.plugins.heti) {
|
||||||
stellar.plugins.heti.enable = false;
|
stellar.plugins.heti.enable = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (stellar.plugins.copycode) {
|
||||||
|
stellar.loadScript(stellar.plugins.copycode.js, { defer: true })
|
||||||
|
}
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue