From 496bbae295bf7a9eddd6135ab841e8c0ae543123 Mon Sep 17 00:00:00 2001 From: pengzhanbo Date: Fri, 29 Dec 2023 00:15:20 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=20content-update=20?= =?UTF-8?q?=E6=8F=92=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugins/plugin-content-update/LICENSE | 21 +++++ plugins/plugin-content-update/README.md | 21 +++++ plugins/plugin-content-update/package.json | 49 ++++++++++ .../src/client/clientConfig.ts | 11 +++ .../src/client/components/Content.ts | 42 +++++++++ .../src/client/composables/index.ts | 19 ++++ .../plugin-content-update/src/client/index.ts | 2 + .../plugin-content-update/src/node/index.ts | 5 ++ .../plugin-content-update/src/node/plugin.ts | 11 +++ plugins/plugin-content-update/src/shim.d.ts | 4 + .../plugin-content-update/tsconfig.build.json | 8 ++ plugins/tsconfig.build.json | 3 +- pnpm-lock.yaml | 90 ++++++++++++------- tsconfig.json | 3 +- 14 files changed, 254 insertions(+), 35 deletions(-) create mode 100644 plugins/plugin-content-update/LICENSE create mode 100644 plugins/plugin-content-update/README.md create mode 100644 plugins/plugin-content-update/package.json create mode 100644 plugins/plugin-content-update/src/client/clientConfig.ts create mode 100644 plugins/plugin-content-update/src/client/components/Content.ts create mode 100644 plugins/plugin-content-update/src/client/composables/index.ts create mode 100644 plugins/plugin-content-update/src/client/index.ts create mode 100644 plugins/plugin-content-update/src/node/index.ts create mode 100644 plugins/plugin-content-update/src/node/plugin.ts create mode 100644 plugins/plugin-content-update/src/shim.d.ts create mode 100644 plugins/plugin-content-update/tsconfig.build.json diff --git a/plugins/plugin-content-update/LICENSE b/plugins/plugin-content-update/LICENSE new file mode 100644 index 00000000..9f677c90 --- /dev/null +++ b/plugins/plugin-content-update/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (C) 2021 - PRESENT by pengzhanbo + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/plugins/plugin-content-update/README.md b/plugins/plugin-content-update/README.md new file mode 100644 index 00000000..22fdd80a --- /dev/null +++ b/plugins/plugin-content-update/README.md @@ -0,0 +1,21 @@ +# `@vuepress-plume/plugin-content-update` + +替换 `@vuepress/client` 的 `` 组件,注入 `onContentUpdated` 生命周期。 +实现当页面内容发生更新时,触发 `onContentUpdated` 事件。 + +## Install +``` +yarn add @vuepress-plume/plugin-content-update +``` +## Usage +``` js +// .vuepress/config.js +const { contentUpdatePlugin } = require('@vuepress-plume/plugin-content-update') +module.exports = { + // ... + plugins: [ + contentUpdatePlugin() + ] + // ... +} +``` diff --git a/plugins/plugin-content-update/package.json b/plugins/plugin-content-update/package.json new file mode 100644 index 00000000..ab711f61 --- /dev/null +++ b/plugins/plugin-content-update/package.json @@ -0,0 +1,49 @@ +{ + "name": "@vuepress-plume/plugin-content-update", + "type": "module", + "version": "1.0.0-rc.6", + "description": "The Plugin for VuePres 2", + "author": "pengzhanbo ", + "license": "MIT", + "homepage": "https://github.com/pengzhanbo/vuepress-theme-plume#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/pengzhanbo/vuepress-theme-plume.git" + }, + "bugs": { + "url": "https://github.com/pengzhanbo/vuepress-theme-plume/issues" + }, + "exports": { + ".": "./lib/node/index.js", + "./client": "./lib/client/index.js", + "./package.json": "./package.json" + }, + "main": "lib/node/index.js", + "types": "./lib/node/index.d.ts", + "files": [ + "lib" + ], + "scripts": { + "build": "pnpm run clean && pnpm run copy && pnpm run ts", + "clean": "rimraf lib *.tsbuildinfo", + "copy": "cpx \"src/**/*.{d.ts,vue,css,scss,jpg,png}\" lib", + "ts": "tsc -b tsconfig.build.json" + }, + "dependencies": { + "@vuepress/client": "2.0.0-rc.0", + "@vuepress/core": "2.0.0-rc.0", + "@vuepress/shared": "2.0.0-rc.0", + "@vuepress/utils": "2.0.0-rc.0", + "vue": "^3.3.13", + "vue-router": "4.2.5" + }, + "publishConfig": { + "access": "public" + }, + "keyword": [ + "VuePress", + "vuepress plugin", + "content-update", + "vuepress-plugin-plugin-content-update" + ] +} diff --git a/plugins/plugin-content-update/src/client/clientConfig.ts b/plugins/plugin-content-update/src/client/clientConfig.ts new file mode 100644 index 00000000..db419180 --- /dev/null +++ b/plugins/plugin-content-update/src/client/clientConfig.ts @@ -0,0 +1,11 @@ +import { defineClientConfig } from '@vuepress/client' +import { Content } from './components/Content.js' + +export default defineClientConfig({ + enhance({ app }) { + if (app._context.components.Content) + delete app._context.components.Content + + app.component('Content', Content) + }, +}) diff --git a/plugins/plugin-content-update/src/client/components/Content.ts b/plugins/plugin-content-update/src/client/components/Content.ts new file mode 100644 index 00000000..7430a828 --- /dev/null +++ b/plugins/plugin-content-update/src/client/components/Content.ts @@ -0,0 +1,42 @@ +import { pagesComponents } from '@internal/pagesComponents' +import { computed, defineComponent, h } from 'vue' +import { usePageData } from '@vuepress/client' +import { runCallbacks } from '../composables/index.js' + +declare const __VUEPRESS_DEV__: boolean + +/** + * Markdown rendered content + */ +export const Content = defineComponent({ + + name: 'Content', + + props: { + pageKey: { + type: String, + required: false, + default: '', + }, + }, + + setup(props) { + const page = usePageData() + const pageComponent = computed( + () => pagesComponents[props.pageKey || page.value.key], + ) + return () => + pageComponent.value + ? h(pageComponent.value, { + onVnodeMounted: runCallbacks, + onVnodeUpdated: runCallbacks, + onVnodeBeforeUnmount: runCallbacks, + }) + : h( + 'div', + __VUEPRESS_DEV__ + ? 'Page does not exist. This is a fallback content.' + : '404 Not Found', + ) + }, +}) diff --git a/plugins/plugin-content-update/src/client/composables/index.ts b/plugins/plugin-content-update/src/client/composables/index.ts new file mode 100644 index 00000000..c61b6972 --- /dev/null +++ b/plugins/plugin-content-update/src/client/composables/index.ts @@ -0,0 +1,19 @@ +import { onUnmounted } from 'vue' + +// eslint-disable-next-line import/no-mutable-exports +export let contentUpdatedCallbacks: (() => any)[] = [] + +/** + * Register callback that is called every time the markdown content is updated + * in the DOM. + */ +export function onContentUpdated(fn: () => any) { + contentUpdatedCallbacks.push(fn) + onUnmounted(() => { + contentUpdatedCallbacks = contentUpdatedCallbacks.filter(f => f !== fn) + }) +} + +export function runCallbacks() { + contentUpdatedCallbacks.forEach(fn => fn()) +} diff --git a/plugins/plugin-content-update/src/client/index.ts b/plugins/plugin-content-update/src/client/index.ts new file mode 100644 index 00000000..5a4bbf87 --- /dev/null +++ b/plugins/plugin-content-update/src/client/index.ts @@ -0,0 +1,2 @@ +export * from './components/Content.js' +export { onContentUpdated } from './composables/index.js' diff --git a/plugins/plugin-content-update/src/node/index.ts b/plugins/plugin-content-update/src/node/index.ts new file mode 100644 index 00000000..429a98f1 --- /dev/null +++ b/plugins/plugin-content-update/src/node/index.ts @@ -0,0 +1,5 @@ +import { contentUpdatePlugin } from './plugin.js' + +export { contentUpdatePlugin } + +export default contentUpdatePlugin diff --git a/plugins/plugin-content-update/src/node/plugin.ts b/plugins/plugin-content-update/src/node/plugin.ts new file mode 100644 index 00000000..02c61177 --- /dev/null +++ b/plugins/plugin-content-update/src/node/plugin.ts @@ -0,0 +1,11 @@ +import type { Plugin } from '@vuepress/core' +import { getDirname, path } from '@vuepress/utils' + +const __dirname = getDirname(import.meta.url) + +export function contentUpdatePlugin(): Plugin { + return { + name: '@vuepress-plume/plugin-content-update', + clientConfigFile: path.resolve(__dirname, '../client/clientConfig.js'), + } +} diff --git a/plugins/plugin-content-update/src/shim.d.ts b/plugins/plugin-content-update/src/shim.d.ts new file mode 100644 index 00000000..603f69cb --- /dev/null +++ b/plugins/plugin-content-update/src/shim.d.ts @@ -0,0 +1,4 @@ +declare module '@internal/pagesComponents' { + const pagesComponents: Record + export { pagesComponents } +} diff --git a/plugins/plugin-content-update/tsconfig.build.json b/plugins/plugin-content-update/tsconfig.build.json new file mode 100644 index 00000000..6bf67375 --- /dev/null +++ b/plugins/plugin-content-update/tsconfig.build.json @@ -0,0 +1,8 @@ +{ + "extends": "../tsconfig.build.json", + "compilerOptions": { + "rootDir": "./src", + "outDir": "./lib" + }, + "include": ["./src"] +} diff --git a/plugins/tsconfig.build.json b/plugins/tsconfig.build.json index c2cf0900..1f591418 100644 --- a/plugins/tsconfig.build.json +++ b/plugins/tsconfig.build.json @@ -13,7 +13,8 @@ { "path": "./plugin-netlify-functions/tsconfig.build.json" }, { "path": "./plugin-notes-data/tsconfig.build.json" }, { "path": "./plugin-page-collection/tsconfig.build.json" }, - { "path": "./plugin-shikiji/tsconfig.build.json" } + { "path": "./plugin-shikiji/tsconfig.build.json" }, + { "path": "./plugin-content-update/tsconfig.build.json" } ], "files": [] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5e574b79..e8bb3e07 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -222,7 +222,7 @@ importers: specifier: ^4.0.0 version: 4.0.0 - plugins/plugin-copy-code: + plugins/plugin-content-update: dependencies: '@vuepress/client': specifier: 2.0.0-rc.0 @@ -243,6 +243,27 @@ importers: specifier: 4.2.5 version: 4.2.5(vue@3.3.13) + plugins/plugin-copy-code: + dependencies: + '@vuepress-plume/plugin-content-update': + specifier: workspace:* + version: link:../plugin-content-update + '@vuepress/client': + specifier: 2.0.0-rc.0 + version: 2.0.0-rc.0(typescript@5.3.3) + '@vuepress/core': + specifier: 2.0.0-rc.0 + version: 2.0.0-rc.0(typescript@5.3.3) + '@vuepress/shared': + specifier: 2.0.0-rc.0 + version: 2.0.0-rc.0 + '@vuepress/utils': + specifier: 2.0.0-rc.0 + version: 2.0.0-rc.0 + vue: + specifier: ^3.3.13 + version: 3.3.13(typescript@5.3.3) + plugins/plugin-iconify: dependencies: '@iconify/vue': @@ -405,6 +426,9 @@ importers: '@vuepress-plume/plugin-caniuse': specifier: workspace:* version: link:../plugins/plugin-caniuse + '@vuepress-plume/plugin-content-update': + specifier: workspace:* + version: link:../plugins/plugin-content-update '@vuepress-plume/plugin-copy-code': specifier: workspace:* version: link:../plugins/plugin-copy-code @@ -484,20 +508,20 @@ importers: specifier: 4.2.5 version: 4.2.5(vue@3.3.13) vuepress-plugin-comment2: - specifier: 2.0.0-rc.6 - version: 2.0.0-rc.6(typescript@5.3.3) + specifier: 2.0.0-rc.7 + version: 2.0.0-rc.7(typescript@5.3.3) vuepress-plugin-md-enhance: - specifier: 2.0.0-rc.6 - version: 2.0.0-rc.6(markdown-it@13.0.2)(typescript@5.3.3) + specifier: 2.0.0-rc.7 + version: 2.0.0-rc.7(markdown-it@13.0.2)(typescript@5.3.3) vuepress-plugin-reading-time2: - specifier: 2.0.0-rc.6 - version: 2.0.0-rc.6(typescript@5.3.3) + specifier: 2.0.0-rc.7 + version: 2.0.0-rc.7(typescript@5.3.3) vuepress-plugin-seo2: - specifier: 2.0.0-rc.6 - version: 2.0.0-rc.6(typescript@5.3.3) + specifier: 2.0.0-rc.7 + version: 2.0.0-rc.7(typescript@5.3.3) vuepress-plugin-sitemap2: - specifier: 2.0.0-rc.6 - version: 2.0.0-rc.6(typescript@5.3.3) + specifier: 2.0.0-rc.7 + version: 2.0.0-rc.7(typescript@5.3.3) devDependencies: '@types/lodash.merge': specifier: ^4.6.9 @@ -16390,8 +16414,8 @@ packages: typescript: 5.3.3 dev: false - /vuepress-plugin-comment2@2.0.0-rc.6(typescript@5.3.3): - resolution: {integrity: sha512-NOGhWS9jrmcFgkaNd5AGtuERok3mbSPBQQ5CV8Uegs0409Zm1L0kmhOPB959Z1KwLxfoNvhD97XruWcQ29bhUw==} + /vuepress-plugin-comment2@2.0.0-rc.7(typescript@5.3.3): + resolution: {integrity: sha512-bZ5BhJ/dQdc24GDc1T95nRCnkjZZo05wpSSU2pI7sRZSeX6MjbpJLMNJPKH3BIMQQQaQUZUIzKLl4U0ja9B07A==} engines: {node: '>=18.16.0', npm: '>=8', pnpm: '>=7', yarn: '>=2'} peerDependencies: '@waline/client': ^2.15.8 || ^3.0.0-alpha.8 @@ -16423,16 +16447,16 @@ packages: giscus: 1.4.0 vue: 3.3.13(typescript@5.3.3) vue-router: 4.2.5(vue@3.3.13) - vuepress-plugin-sass-palette: 2.0.0-rc.6(typescript@5.3.3) - vuepress-shared: 2.0.0-rc.6(typescript@5.3.3) + vuepress-plugin-sass-palette: 2.0.0-rc.7(typescript@5.3.3) + vuepress-shared: 2.0.0-rc.7(typescript@5.3.3) transitivePeerDependencies: - '@vue/composition-api' - supports-color - typescript dev: false - /vuepress-plugin-md-enhance@2.0.0-rc.6(markdown-it@13.0.2)(typescript@5.3.3): - resolution: {integrity: sha512-cEsMccjqdNFq4UjnFbg9OlBwrIF9Ducr2MX2G+6p4h17yJ8yf7NctpGZwnVMh2FGmQ7oYjcIpkuUDrkLn4elzw==} + /vuepress-plugin-md-enhance@2.0.0-rc.7(markdown-it@13.0.2)(typescript@5.3.3): + resolution: {integrity: sha512-UHcsPNbbg9itmIndTKn5nObjy/eVzbNo+6A9P1JaOPfNukkC6H7LaHHgwMlPXNsmaeYZmR18ZA+NCSTGcRDTvQ==} engines: {node: '>=18.16.0', npm: '>=8', pnpm: '>=7', yarn: '>=2'} peerDependencies: '@types/reveal.js': ^4.4.5 @@ -16518,8 +16542,8 @@ packages: js-yaml: 4.1.0 vue: 3.3.13(typescript@5.3.3) vue-router: 4.2.5(vue@3.3.13) - vuepress-plugin-sass-palette: 2.0.0-rc.6(typescript@5.3.3) - vuepress-shared: 2.0.0-rc.6(typescript@5.3.3) + vuepress-plugin-sass-palette: 2.0.0-rc.7(typescript@5.3.3) + vuepress-shared: 2.0.0-rc.7(typescript@5.3.3) transitivePeerDependencies: - '@vue/composition-api' - markdown-it @@ -16527,8 +16551,8 @@ packages: - typescript dev: false - /vuepress-plugin-reading-time2@2.0.0-rc.6(typescript@5.3.3): - resolution: {integrity: sha512-GgyKWS66QvlrXV2zMF0qhgtEpELvN0kSOEAqgGn8mR+01TgLirdq+k9rExp1zab7UH7h8FjtRgWlcYgfPUbGEA==} + /vuepress-plugin-reading-time2@2.0.0-rc.7(typescript@5.3.3): + resolution: {integrity: sha512-OBFxXNZQGOyhzIx2ZfJ/nPBiFJYRGOCT+1GrZRjeW0cfrdvgYZo6x2jDBDtmrrzT3TlhZRpQDZB6QMbiORQhPQ==} engines: {node: '>=18.16.0', npm: '>=8', pnpm: '>=7', yarn: '>=2'} peerDependencies: vuepress: 2.0.0-rc.0 @@ -16544,15 +16568,15 @@ packages: dependencies: '@vuepress/client': 2.0.0-rc.0(typescript@5.3.3) vue: 3.3.13(typescript@5.3.3) - vuepress-shared: 2.0.0-rc.6(typescript@5.3.3) + vuepress-shared: 2.0.0-rc.7(typescript@5.3.3) transitivePeerDependencies: - '@vue/composition-api' - supports-color - typescript dev: false - /vuepress-plugin-sass-palette@2.0.0-rc.6(typescript@5.3.3): - resolution: {integrity: sha512-/LAcJvznI5C/cSO0IM2btGivA9IgOON+YwpEzHGhkZKwBKx/lLqOpHH4ghaKmC/hX72QISyM1pjQJ/9pjOQEOg==} + /vuepress-plugin-sass-palette@2.0.0-rc.7(typescript@5.3.3): + resolution: {integrity: sha512-xi8UDaPGS67MVzUDoaQN67dZoTjkW30KpHQJH8R/6DybOz9hC0oVqvkZM9waPPCCdcPytxVUfVDdincARZ4eHw==} engines: {node: '>=18.16.0', npm: '>=8', pnpm: '>=7', yarn: '>=2'} peerDependencies: sass-loader: ^13.3.2 @@ -16573,15 +16597,15 @@ packages: '@vuepress/utils': 2.0.0-rc.0 chokidar: 3.5.3 sass: 1.69.5 - vuepress-shared: 2.0.0-rc.6(typescript@5.3.3) + vuepress-shared: 2.0.0-rc.7(typescript@5.3.3) transitivePeerDependencies: - '@vue/composition-api' - supports-color - typescript dev: false - /vuepress-plugin-seo2@2.0.0-rc.6(typescript@5.3.3): - resolution: {integrity: sha512-ZvYQNV/aZV5iCi7D7qg1Bz7rrQ00f9exPQ+m/JEsJr+uH0g1frAbCI46Ilu0Y42+XTU6id/wO23yKoS0GFQ8jw==} + /vuepress-plugin-seo2@2.0.0-rc.7(typescript@5.3.3): + resolution: {integrity: sha512-WHn4s1N2cHPQZQh+rZyiH9mDtGYFh9E2F5ZUV3LT2IddGuHluzuwVScIxix9q76AvbdCl4rhg7vr97oc8oPoUA==} engines: {node: '>=18.16.0', npm: '>=8', pnpm: '>=7', yarn: '>=2'} peerDependencies: vuepress: 2.0.0-rc.0 @@ -16597,15 +16621,15 @@ packages: dependencies: '@vuepress/shared': 2.0.0-rc.0 '@vuepress/utils': 2.0.0-rc.0 - vuepress-shared: 2.0.0-rc.6(typescript@5.3.3) + vuepress-shared: 2.0.0-rc.7(typescript@5.3.3) transitivePeerDependencies: - '@vue/composition-api' - supports-color - typescript dev: false - /vuepress-plugin-sitemap2@2.0.0-rc.6(typescript@5.3.3): - resolution: {integrity: sha512-b9gNdmaUsXRBpE1OKkTmp/WhCBKQgkHQHhEK1oK9oZiCEAP4Xhmnob5UhtS7WeBK9HBsjCCCUwAEBbNZ8WdiEw==} + /vuepress-plugin-sitemap2@2.0.0-rc.7(typescript@5.3.3): + resolution: {integrity: sha512-Vc13ucmamsXu0PD9Gu1lRm0NKOAwV/h3hZA+h2jAnavsiAqkAUF1WmvjNLPMWCVz77lez3knQNpWDoHZVBoxLQ==} engines: {node: '>=18.16.0', npm: '>=8', pnpm: '>=7', yarn: '>=2'} peerDependencies: vuepress: 2.0.0-rc.0 @@ -16622,15 +16646,15 @@ packages: '@vuepress/shared': 2.0.0-rc.0 '@vuepress/utils': 2.0.0-rc.0 sitemap: 7.1.1 - vuepress-shared: 2.0.0-rc.6(typescript@5.3.3) + vuepress-shared: 2.0.0-rc.7(typescript@5.3.3) transitivePeerDependencies: - '@vue/composition-api' - supports-color - typescript dev: false - /vuepress-shared@2.0.0-rc.6(typescript@5.3.3): - resolution: {integrity: sha512-bcEBxOX0ulWtCeRCBOdIpvFC+m4HvyWGLm6CPXedPiHaSl6avp/S6akYNcj2dyBPXxC5v3WfiGJDumis0fqYbg==} + /vuepress-shared@2.0.0-rc.7(typescript@5.3.3): + resolution: {integrity: sha512-1EUgbOe8/VK0yuzau2mtL22Av2547zVJP/q2niCoCyBTzMrn0agaWSRIDhhQx+e4xPlE5Mi3FsCHDXTfkWSuIw==} engines: {node: '>=18.16.0', npm: '>=8', pnpm: '>=7', yarn: '>=2'} peerDependencies: vuepress: 2.0.0-rc.0 diff --git a/tsconfig.json b/tsconfig.json index e5590835..4f8e6589 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,6 +10,7 @@ "@internal/notesData": [ "./plugins/plugin-notes-data/src/client/notesData.d.ts" ], + "@internal/pageComponents": ["./docs/.vuepress/.temp/internal/pageComponents.js"], "@internal/*": ["./docs/.vuepress/.temp/internal/*"], "@vuepress-plume/*": ["./plugins/*/src/node/index.ts"], "vuepress-theme-plume": ["./theme/src/node/index.ts"], @@ -25,5 +26,5 @@ "docs/.vuepress/**/*", "scripts/**/*" ], - "exclude": ["node_modules", ".temp", ".cache", "lib", "dist"] + "exclude": ["node_modules", ".cache", "lib", "dist"] }