diff --git a/docs/.vuepress/theme.ts b/docs/.vuepress/theme.ts
index f6365c864e..2c3e2b8f36 100644
--- a/docs/.vuepress/theme.ts
+++ b/docs/.vuepress/theme.ts
@@ -59,6 +59,9 @@ export default defaultTheme({
},
themePlugins: {
+ copyCode: {
+ inline: true,
+ },
git: {
contributors: {
avatar: true,
diff --git a/docs/plugins/features/copy-code.md b/docs/plugins/features/copy-code.md
index dd2b139102..2257d90938 100644
--- a/docs/plugins/features/copy-code.md
+++ b/docs/plugins/features/copy-code.md
@@ -56,13 +56,23 @@ export default {
### ignoreSelector
-- Type: `string[]`
+- Type: `string[] | string`
- Details:
Elements selector in code blocks, used to ignore related elements when copying.
For example, `['.token.comment']` will ignore nodes with the class name `.token.comment` in code blocks (which in `prismjs` refers to ignoring comments).
+### inlineSelector
+
+- Type: `string[] | string | boolean`
+- Default: `false`
+
+ Whether to copy inline code content when double click.
+
+ - `boolean`: Whether to copy inline code content when double click.
+ - `string | string[]`: The selector of inline code.
+
### transform
- Type: `(preElement: HTMLPreElement) => void`
diff --git a/docs/zh/plugins/features/copy-code.md b/docs/zh/plugins/features/copy-code.md
index b3ce3d0549..bd7bfe06e0 100644
--- a/docs/zh/plugins/features/copy-code.md
+++ b/docs/zh/plugins/features/copy-code.md
@@ -56,13 +56,24 @@ export default {
### ignoreSelector
-- 类型:`string[]`
+- 类型:`string[] | string`
- 详情:
代码块中的元素选择器,用于在复制时忽略相关元素。
例如: `['.token.comment']` 将忽略代码块中类名为 `.token.comment` 的节点 (这会在 `prismjs` 中忽略注释)。
+### inlineSelector
+
+- 类型:`string[] | string | boolean`
+- 默认值:`false`
+- 详情:
+
+ 是否在双击时复制行内代码内容。
+
+ - `boolean`: 是否在双击时复制行内代码内容。
+ - `string[] | string`: 选择器,表示需要复制的行内代码内容。
+
### transform
- 类型:`(preElement: HTMLPreElement) => void`
diff --git a/plugins/features/plugin-copy-code/rollup.config.ts b/plugins/features/plugin-copy-code/rollup.config.ts
index 4a44353832..c168c8ced6 100644
--- a/plugins/features/plugin-copy-code/rollup.config.ts
+++ b/plugins/features/plugin-copy-code/rollup.config.ts
@@ -10,7 +10,7 @@ export default [
files: ['config', 'index'],
},
{
- dtsExternal: ['@vuepress/helper/shared'],
+ dtsExternal: ['@vuepress/helper/client', '@vuepress/helper/shared'],
},
),
]
diff --git a/plugins/features/plugin-copy-code/src/client/composables/useCopyCode.ts b/plugins/features/plugin-copy-code/src/client/composables/useCopyCode.ts
index 02647eedb3..22e817c58e 100644
--- a/plugins/features/plugin-copy-code/src/client/composables/useCopyCode.ts
+++ b/plugins/features/plugin-copy-code/src/client/composables/useCopyCode.ts
@@ -1,4 +1,4 @@
-import { useLocaleConfig } from '@vuepress/helper/client'
+import { Message, useLocaleConfig } from '@vuepress/helper/client'
import {
useClipboard,
useEventListener,
@@ -9,19 +9,19 @@ import { computed } from 'vue'
import { onContentUpdated } from 'vuepress/client'
import type { CopyCodePluginLocaleConfig } from '../types.js'
+import '@vuepress/helper/message.css'
import '../styles/copy-code.css'
import '../styles/vars.css'
export interface UseCopyCodeOptions {
locales: CopyCodePluginLocaleConfig
- selector: string[]
+ selector: string
+ ignoreSelector?: string
+ inlineSelector?: string
/** @default 2000 */
duration: number
/** @default false */
showInMobile?: boolean
- /** @default [] */
- ignoreSelector?: string[]
-
/**
* Transform pre element before copy
*
@@ -44,14 +44,17 @@ export interface UseCopyCodeOptions {
transform?: (preElement: HTMLElement) => void
}
+const CHECK_ICON =
+ ''
const SHELL_RE = /language-(shellscript|shell|bash|sh|zsh)/
export const useCopyCode = ({
+ selector,
+ ignoreSelector,
+ inlineSelector,
duration = 2000,
locales,
- selector,
showInMobile,
- ignoreSelector = [],
transform,
}: UseCopyCodeOptions): void => {
if (__VUEPRESS_SSR__) return
@@ -83,9 +86,7 @@ export const useCopyCode = ({
document.body.classList.toggle('no-copy-code', !enabled.value)
if (!enabled.value) return
- document
- .querySelectorAll(selector.join(','))
- .forEach(insertCopyButton)
+ document.querySelectorAll(selector).forEach(insertCopyButton)
}
watchImmediate(enabled, appendCopyButton, {
@@ -98,6 +99,7 @@ export const useCopyCode = ({
const { copy } = useClipboard({ legacy: true })
const timeoutIdMap = new WeakMap>()
+ let message: Message | null = null
const copyContent = async (
codeContainer: HTMLDivElement,
@@ -106,8 +108,8 @@ export const useCopyCode = ({
): Promise => {
const clone = codeContent.cloneNode(true) as HTMLPreElement
- if (ignoreSelector.length) {
- clone.querySelectorAll(ignoreSelector.join(',')).forEach((node) => {
+ if (ignoreSelector) {
+ clone.querySelectorAll(ignoreSelector).forEach((node) => {
node.remove()
})
}
@@ -148,4 +150,28 @@ export const useCopyCode = ({
void copyContent(codeContainer, preBlock, el as HTMLButtonElement)
}
})
+
+ if (inlineSelector) {
+ useEventListener('dblclick', (event) => {
+ const el = event.target as HTMLElement
+
+ if (enabled.value && el.matches(inlineSelector)) {
+ const selection = window.getSelection()
+
+ if (
+ selection &&
+ (el.contains(selection.anchorNode) ||
+ el.contains(selection.focusNode))
+ ) {
+ selection.removeAllRanges()
+ }
+
+ void copy(el.textContent || '')
+ ;(message ??= new Message()).pop(
+ `${CHECK_ICON}${locale.value.copied} `,
+ duration,
+ )
+ }
+ })
+ }
}
diff --git a/plugins/features/plugin-copy-code/src/client/config.ts b/plugins/features/plugin-copy-code/src/client/config.ts
index 5283213d78..d62f4fe9c7 100644
--- a/plugins/features/plugin-copy-code/src/client/config.ts
+++ b/plugins/features/plugin-copy-code/src/client/config.ts
@@ -4,8 +4,9 @@ import type { CopyCodePluginLocaleConfig } from './types.js'
declare const __CC_DURATION__: number
declare const __CC_LOCALES__: CopyCodePluginLocaleConfig
-declare const __CC_SELECTOR__: string[]
-declare const __CC_IGNORE_SELECTOR__: string[]
+declare const __CC_SELECTOR__: string
+declare const __CC_IGNORE_SELECTOR__: string
+declare const __CC_INLINE_SELECTOR__: string
declare const __CC_SHOW_IN_MOBILE__: boolean
export default defineClientConfig({
@@ -13,6 +14,7 @@ export default defineClientConfig({
useCopyCode({
selector: __CC_SELECTOR__,
ignoreSelector: __CC_IGNORE_SELECTOR__,
+ inlineSelector: __CC_INLINE_SELECTOR__,
locales: __CC_LOCALES__,
duration: __CC_DURATION__,
showInMobile: __CC_SHOW_IN_MOBILE__,
diff --git a/plugins/features/plugin-copy-code/src/node/copyCodePlugin.ts b/plugins/features/plugin-copy-code/src/node/copyCodePlugin.ts
index 871232d9c7..4cec6a3bcc 100644
--- a/plugins/features/plugin-copy-code/src/node/copyCodePlugin.ts
+++ b/plugins/features/plugin-copy-code/src/node/copyCodePlugin.ts
@@ -21,19 +21,26 @@ export const copyCodePlugin =
name: PLUGIN_NAME,
define: () => ({
- __CC_DURATION__: options.duration ?? 2000,
- __CC_IGNORE_SELECTOR__: options.ignoreSelector ?? [],
+ __CC_SELECTOR__: isArray(options.selector)
+ ? options.selector.join(',')
+ : (options.selector ?? '[vp-content] div[class*="language-"] pre'),
+ __CC_IGNORE_SELECTOR__: Array.isArray(options.ignoreSelector)
+ ? options.ignoreSelector.join(',')
+ : (options.ignoreSelector ?? ''),
+ __CC_INLINE_SELECTOR__: Array.isArray(options.inline)
+ ? options.inline.join(',')
+ : isString(options.inline)
+ ? options.inline
+ : options.inline
+ ? '[vp-content] :not(pre) > code'
+ : '',
__CC_LOCALES__: getFullLocaleConfig({
app,
name: PLUGIN_NAME,
default: copyCodeLocaleInfo,
config: options.locales,
}),
- __CC_SELECTOR__: isArray(options.selector)
- ? options.selector
- : isString(options.selector)
- ? [options.selector]
- : ['[vp-content] div[class*="language-"] pre'],
+ __CC_DURATION__: options.duration ?? 2000,
__CC_SHOW_IN_MOBILE__: options.showInMobile ?? false,
}),
diff --git a/plugins/features/plugin-copy-code/src/node/options.ts b/plugins/features/plugin-copy-code/src/node/options.ts
index ac6577d9f8..ea6301b4cd 100644
--- a/plugins/features/plugin-copy-code/src/node/options.ts
+++ b/plugins/features/plugin-copy-code/src/node/options.ts
@@ -40,7 +40,7 @@ export interface CopyCodePluginOptions {
*
* @default []
*/
- ignoreSelector?: string[]
+ ignoreSelector?: string[] | string
/**
* Locale config
@@ -48,4 +48,19 @@ export interface CopyCodePluginOptions {
* 国际化配置
*/
locales?: LocaleConfig
+
+ /**
+ * Whether to copy inline code content when double click.
+ *
+ * - boolean: Whether to copy inline code content when double click.
+ * - string | string[]: The selector of inline code.
+ *
+ * 是否在双击时复制内联代码内容
+ *
+ * - boolean: 是否在双击时复制内联代码内容
+ * - string | string[]: 内联代码的选择器
+ *
+ * @default '[vp-content] :not(pre) > code'
+ */
+ inline?: string[] | boolean | string
}