Skip to content

Commit

Permalink
feat: use global delegation for copy code interaction
Browse files Browse the repository at this point in the history
  • Loading branch information
yyx990803 committed Aug 30, 2022
1 parent 1e312f5 commit b5bd73f
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 49 deletions.
@@ -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) {
Expand Down Expand Up @@ -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)
})
}
}
4 changes: 4 additions & 0 deletions src/client/app/index.ts
Expand Up @@ -16,6 +16,7 @@ import { usePrefetch } from './composables/preFetch.js'
import { dataSymbol, initData } from './data.js'
import { Content } from './components/Content.js'
import { ClientOnly } from './components/ClientOnly.js'
import { useCopyCode } from './composables/copyCode.js'

const NotFound = Theme.NotFound || (() => '404 Not Found')

Expand All @@ -40,6 +41,9 @@ const VitePressApp = defineComponent({
usePrefetch()
}

// setup global copy code handler
useCopyCode()

if (Theme.setup) Theme.setup()
return () => h(Theme.Layout)
}
Expand Down
3 changes: 0 additions & 3 deletions src/client/theme-default/components/VPContent.vue
@@ -1,6 +1,5 @@
<script setup lang="ts">
import { useRoute, useData } from 'vitepress'
import { useCopyCode } from '../composables/copy-code.js'
import { useSidebar } from '../composables/sidebar.js'
import VPPage from './VPPage.vue'
import VPHome from './VPHome.vue'
Expand All @@ -12,8 +11,6 @@ const { frontmatter } = useData()
const { hasSidebar } = useSidebar()
const NotFound = inject('NotFound')
useCopyCode()
</script>

<template>
Expand Down

0 comments on commit b5bd73f

Please sign in to comment.