perf(theme): watermark options

This commit is contained in:
pengzhanbo 2024-05-10 13:52:33 +08:00
parent 0afd3e59ef
commit 2238637d94
6 changed files with 85 additions and 36 deletions

View File

@ -32,6 +32,12 @@ export default defineUserConfig({
enabled: page => true, // function 类型 过滤哪些页面启用水印
delay: 500, // 添加水印的延时。以毫秒为单位。
/**
* 是否全屏水印,默认为 `true`
* 设置为 `false` 时,水印仅在 内容区域中显示。
*/
fullPage: true,
/** @see https://zhensherlock.github.io/watermark-js-plus/zh/config/ */
watermarkOptions: {
content: 'your watermark',
@ -175,6 +181,28 @@ watermark:
---
```
## Frontmatter
主题支持在 md 文件中添加 `frontmatter.watermark` 为单个页面设置水印。
```md
---
watermark:
content: My Custom Content
---
```
支持的配置项请参考:[watermark-js-plus](https://zhensherlock.github.io/watermark-js-plus/zh/config/)
同时,还额外支持 `fullPage` 控制是否全屏显示。
```md
---
watermark:
fullPage: false
---
```
## 示例
- [内容水印](/article/2z59hh8g/)

View File

@ -40,7 +40,7 @@ export async function netlifyServe({
// '--debug',
]
const { stdout, cancel } = execa(
const { stdout, kill } = execa(
path.resolve(__dirname, '../../../node_modules/.bin/netlify'),
argv,
{
@ -54,6 +54,6 @@ export async function netlifyServe({
return {
host: `http://localhost:${port}`,
close: () => cancel(),
close: () => kill(),
}
}

View File

@ -3,12 +3,15 @@ import { computed } from 'vue'
import { usePageFrontmatter } from 'vuepress/client'
import type { PlumeThemePageFrontmatter } from '../../shared/index.js'
declare const __PLUME_WM_FP__: boolean
export function setupWatermark(): void {
const frontmatter = usePageFrontmatter<PlumeThemePageFrontmatter>()
defineWatermarkConfig(computed(() => ({
parent: typeof frontmatter.value.watermark === 'object'
? frontmatter.value.watermark.fullPage === false ? '.plume-content' : 'body'
: 'body',
})))
defineWatermarkConfig(computed(() => {
const disableFullPage = typeof frontmatter.value.watermark === 'object' && frontmatter.value.watermark.fullPage === false
return {
parent: !__PLUME_WM_FP__ || disableFullPage ? '.plume-content' : 'body',
}
}))
}

View File

@ -0,0 +1,31 @@
import type { Page } from 'vuepress'
import type { PlumeThemeLocaleOptions } from '../shared/index.js'
export function resolvePageHead(page: Page, localeOptions: PlumeThemeLocaleOptions) {
page.frontmatter.head ??= []
if (localeOptions.appearance ?? true) {
const appearance = typeof localeOptions.appearance === 'string'
? localeOptions.appearance
: 'auto'
page.frontmatter.head.push([
'script',
{ id: 'check-dark-mode' },
appearance === 'force-dark'
? `document.documentElement.classList.add('dark')`
: `;(function () {
const um= localStorage.getItem('vuepress-theme-appearance') || '${appearance}';
const sm = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
if (um === 'dark' || (um !== 'light' && sm)) {
document.documentElement.classList.add('dark');
}
})();`.replace(/^\s+|\s+$/gm, '').replace(/\n/g, ''),
])
}
page.frontmatter.head?.push([
'script',
{ id: 'check-mac-os' },
`document.documentElement.classList.toggle('mac', /Mac|iPhone|iPod|iPad/i.test(navigator.platform))`,
])
}

View File

@ -1,12 +1,13 @@
import type { Page, Theme } from 'vuepress/core'
import { logger, templateRenderer } from 'vuepress/utils'
import { addViteConfig } from '@vuepress/helper'
import { addViteConfig, isPlainObject } from '@vuepress/helper'
import type { PlumeThemeOptions, PlumeThemePageData } from '../shared/index.js'
import { mergeLocaleOptions } from './defaultOptions.js'
import { setupPlugins } from './plugins.js'
import { extendsPageData, setupPage } from './setupPages.js'
import { getThemePackage, resolve, templates } from './utils.js'
import { resolveEncrypt } from './resolveEncrypt.js'
import { resolvePageHead } from './resolvePageHead.js'
const THEME_NAME = 'vuepress-theme-plume'
@ -18,6 +19,9 @@ export function plumeTheme({
}: PlumeThemeOptions = {}): Theme {
const pluginsOptions = plugins ?? themePlugins ?? {}
const pkg = getThemePackage()
const watermarkFullPage = isPlainObject(pluginsOptions.watermark)
? pluginsOptions.watermark.fullPage !== false
: true
if (themePlugins) {
logger.warn(
@ -29,43 +33,25 @@ export function plumeTheme({
localeOptions = mergeLocaleOptions(app, localeOptions)
return {
name: THEME_NAME,
define: {
...resolveEncrypt(encrypt),
__PLUME_WM_FP__: watermarkFullPage,
},
templateBuild: templates('build.html'),
clientConfigFile: resolve('client/config.js'),
plugins: setupPlugins(app, pluginsOptions, localeOptions, encrypt),
onInitialized: app => setupPage(app, localeOptions),
extendsPage: (page) => {
extendsPageData(app, page as Page<PlumeThemePageData>, localeOptions)
page.frontmatter.head ??= []
if (localeOptions.appearance ?? true) {
const appearance = typeof localeOptions.appearance === 'string'
? localeOptions.appearance
: 'auto'
page.frontmatter.head.push([
'script',
{ id: 'check-dark-mode' },
appearance === 'force-dark'
? `document.documentElement.classList.add('dark')`
: `;(function () {
const um= localStorage.getItem('vuepress-theme-appearance') || '${appearance}';
const sm = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
if (um === 'dark' || (um !== 'light' && sm)) {
document.documentElement.classList.add('dark');
}
})();`.replace(/^\s+|\s+$/gm, '').replace(/\n/g, ''),
])
}
page.frontmatter.head?.push([
'script',
{ id: 'check-mac-os' },
`document.documentElement.classList.toggle('mac', /Mac|iPhone|iPod|iPad/i.test(navigator.platform))`,
])
resolvePageHead(page, localeOptions)
},
templateBuildRenderer(template, context) {
template = template
.replace('{{ themeVersion }}', pkg.version || '')
@ -73,6 +59,7 @@ export function plumeTheme({
.replace(/\n/g, '')
return templateRenderer(template, context)
},
extendsBundlerOptions: (options, app) => {
addViteConfig(options, app, {
server: { fs: { cachedChecks: false } },

View File

@ -74,5 +74,5 @@ export interface PlumeThemePluginOptions {
/**
*
*/
watermark?: boolean | WatermarkPluginOptions
watermark?: boolean | (WatermarkPluginOptions & { fullPage?: boolean })
}