|
|
|
@ -1,23 +1,37 @@
|
|
|
|
|
import { nextTick, watch } from 'vue'
|
|
|
|
|
import { inBrowser, useData } from 'vitepress'
|
|
|
|
|
import { inBrowser } from '../utils.js'
|
|
|
|
|
|
|
|
|
|
export function useCopyCode() {
|
|
|
|
|
const { page } = useData()
|
|
|
|
|
|
|
|
|
|
if (inBrowser)
|
|
|
|
|
watch(
|
|
|
|
|
() => page.value.relativePath,
|
|
|
|
|
() => {
|
|
|
|
|
nextTick(() => {
|
|
|
|
|
document
|
|
|
|
|
.querySelectorAll<HTMLSpanElement>(
|
|
|
|
|
'.vp-doc div[class*="language-"] > button.copy'
|
|
|
|
|
)
|
|
|
|
|
.forEach(handleElement)
|
|
|
|
|
if (inBrowser) {
|
|
|
|
|
window.addEventListener('click', (e) => {
|
|
|
|
|
const el = e.target as HTMLElement
|
|
|
|
|
if (el.matches('div[class*="language-"] > button.copy')) {
|
|
|
|
|
const parent = el.parentElement
|
|
|
|
|
const sibling = el.nextElementSibling
|
|
|
|
|
?.nextElementSibling as HTMLPreElement | null
|
|
|
|
|
if (!parent || !sibling) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const isShell = /language-(shellscript|shell|bash|sh|zsh)/.test(
|
|
|
|
|
parent.classList.toString()
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
let { innerText: text = '' } = sibling
|
|
|
|
|
|
|
|
|
|
if (isShell) {
|
|
|
|
|
text = text.replace(/^ *(\$|>) /gm, '')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
copyToClipboard(text).then(() => {
|
|
|
|
|
el.classList.add('copied')
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
el.classList.remove('copied')
|
|
|
|
|
el.blur()
|
|
|
|
|
}, 2000)
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
{ immediate: true, flush: 'post' }
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function copyToClipboard(text: string) {
|
|
|
|
@ -63,32 +77,3 @@ async function copyToClipboard(text: string) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function handleElement(el: HTMLElement) {
|
|
|
|
|
el.onclick = () => {
|
|
|
|
|
const parent = el.parentElement
|
|
|
|
|
const sibling = el.nextElementSibling
|
|
|
|
|
?.nextElementSibling as HTMLPreElement | null
|
|
|
|
|
if (!parent || !sibling) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const isShell = /language-(shellscript|shell|bash|sh|zsh)/.test(
|
|
|
|
|
parent.classList.toString()
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
let { innerText: text = '' } = sibling
|
|
|
|
|
|
|
|
|
|
if (isShell) {
|
|
|
|
|
text = text.replace(/^ *(\$|>) /gm, '')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
copyToClipboard(text).then(() => {
|
|
|
|
|
el.classList.add('copied')
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
el.classList.remove('copied')
|
|
|
|
|
el.blur()
|
|
|
|
|
}, 2000)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|