From 7019c3ee493fc1bd379a0f81eb42bc1a606b162a Mon Sep 17 00:00:00 2001 From: "Mr.Hope" Date: Mon, 17 Jan 2022 21:01:36 +0800 Subject: [PATCH 1/7] feat(plugin-external-link-icon): use i18n hint as icon default slot --- docs/.vuepress/config.ts | 7 ++++++- .../client/__tests__/__fixtures__/siteData.ts | 2 -- .../src/client/components/ExternalLinkIcon.ts | 13 ++++++++++++- .../src/client/styles/external-link-icon.css | 13 +++++++++++++ .../src/node/externalLinkIconPlugin.ts | 17 ++++++++++++++--- .../src/client/clientAppEnhance.ts | 5 ----- .../components/global/ExternalLinkIcon.vue | 12 ------------ .../theme-default/src/node/defaultTheme.ts | 2 +- .../node/utils/assignDefaultLocaleOptions.ts | 1 - .../theme-default/src/shared/options.ts | 8 ++------ 10 files changed, 48 insertions(+), 32 deletions(-) delete mode 100644 packages/@vuepress/theme-default/src/client/components/global/ExternalLinkIcon.vue diff --git a/docs/.vuepress/config.ts b/docs/.vuepress/config.ts index d0f7e92c0f..86fa67f191 100644 --- a/docs/.vuepress/config.ts +++ b/docs/.vuepress/config.ts @@ -129,13 +129,18 @@ export default defineUserConfig({ backToHome: '返回首页', // a11y - openInNewWindow: '在新窗口打开', toggleDarkMode: '切换夜间模式', toggleSidebar: '切换侧边栏', }, }, themePlugins: { + externalLinkIcon: { + i18n: { + '/zh/': '在新窗口打开', + }, + }, + // only enable git plugin in production mode git: isProd, }, diff --git a/packages/@vuepress/client/__tests__/__fixtures__/siteData.ts b/packages/@vuepress/client/__tests__/__fixtures__/siteData.ts index 534520e6c8..9cb270e95c 100644 --- a/packages/@vuepress/client/__tests__/__fixtures__/siteData.ts +++ b/packages/@vuepress/client/__tests__/__fixtures__/siteData.ts @@ -29,7 +29,6 @@ export const siteData = { "Looks like we've got some broken links.", ], backToHome: 'Take me home', - openInNewWindow: 'open in new window', }, '/zh/': { info: '提示', @@ -42,7 +41,6 @@ export const siteData = { '看起来我们进入了错误的链接', ], backToHome: '返回首页', - openInNewWindow: '在新窗口打开', }, }, }, diff --git a/packages/@vuepress/plugin-external-link-icon/src/client/components/ExternalLinkIcon.ts b/packages/@vuepress/plugin-external-link-icon/src/client/components/ExternalLinkIcon.ts index bfe428d93d..b54086e158 100644 --- a/packages/@vuepress/plugin-external-link-icon/src/client/components/ExternalLinkIcon.ts +++ b/packages/@vuepress/plugin-external-link-icon/src/client/components/ExternalLinkIcon.ts @@ -1,9 +1,12 @@ +import { useRouteLocale } from '@vuepress/client' import { h } from 'vue' import type { FunctionalComponent } from 'vue' import '../styles/vars.css' import '../styles/external-link-icon.css' +declare const EXTERNAL_LINK_ICON_I18N: Record + const svg = h( 'svg', { @@ -31,6 +34,14 @@ const svg = h( ) export const ExternalLinkIcon: FunctionalComponent = (_, { slots }) => - h('span', [svg, slots.default?.()]) + h('span', [ + svg, + slots.default?.() || + h( + 'span', + { class: 'external-link-sr-only-text' }, + EXTERNAL_LINK_ICON_I18N[useRouteLocale().value] || 'open in new window' + ), + ]) ExternalLinkIcon.displayName = 'ExternalLinkIcon' diff --git a/packages/@vuepress/plugin-external-link-icon/src/client/styles/external-link-icon.css b/packages/@vuepress/plugin-external-link-icon/src/client/styles/external-link-icon.css index e04d3f9e0d..9ac51bdf61 100644 --- a/packages/@vuepress/plugin-external-link-icon/src/client/styles/external-link-icon.css +++ b/packages/@vuepress/plugin-external-link-icon/src/client/styles/external-link-icon.css @@ -5,3 +5,16 @@ vertical-align: middle; top: -1px; } + +.external-link-sr-only-text { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border-width: 0; + user-select: none; +} diff --git a/packages/@vuepress/plugin-external-link-icon/src/node/externalLinkIconPlugin.ts b/packages/@vuepress/plugin-external-link-icon/src/node/externalLinkIconPlugin.ts index ff5bc7d394..7894020f82 100644 --- a/packages/@vuepress/plugin-external-link-icon/src/node/externalLinkIconPlugin.ts +++ b/packages/@vuepress/plugin-external-link-icon/src/node/externalLinkIconPlugin.ts @@ -2,11 +2,22 @@ import type { Plugin } from '@vuepress/core' import type { MarkdownEnv } from '@vuepress/markdown' import { path } from '@vuepress/utils' -export type ExternalLinkIconPluginOptions = Record +export type ExternalLinkIconPluginOptions = { + /** + * i18n config + */ + i18n: Record +} -export const externalLinkIconPlugin: Plugin = { +export const externalLinkIconPlugin: Plugin = ( + options +) => ({ name: '@vuepress/plugin-external-link-icon', + alias: { + EXTERNAL_LINK_ICON_I18N: options.i18n, + }, + clientAppEnhanceFiles: path.resolve( __dirname, '../client/clientAppEnhance.js' @@ -44,4 +55,4 @@ export const externalLinkIconPlugin: Plugin = { return result } }, -} +}) diff --git a/packages/@vuepress/theme-default/src/client/clientAppEnhance.ts b/packages/@vuepress/theme-default/src/client/clientAppEnhance.ts index a96b5e90c4..33b5cf8c6d 100644 --- a/packages/@vuepress/theme-default/src/client/clientAppEnhance.ts +++ b/packages/@vuepress/theme-default/src/client/clientAppEnhance.ts @@ -3,7 +3,6 @@ import { h } from 'vue' import Badge from './components/global/Badge.vue' import CodeGroup from './components/global/CodeGroup' import CodeGroupItem from './components/global/CodeGroupItem.vue' -import ExternalLinkIcon from './components/global/ExternalLinkIcon.vue' import { useScrollPromise } from './composables' import './styles/index.scss' @@ -13,10 +12,6 @@ export default defineClientAppEnhance(({ app, router }) => { app.component('CodeGroup', CodeGroup) app.component('CodeGroupItem', CodeGroupItem) - // override the `` provided by @vuepress/plugin-external-link-icon - delete app._context.components.ExternalLinkIcon - app.component('ExternalLinkIcon', ExternalLinkIcon) - // compat with @vuepress/plugin-docsearch and @vuepress/plugin-search app.component('NavbarSearch', () => { const SearchComponent = diff --git a/packages/@vuepress/theme-default/src/client/components/global/ExternalLinkIcon.vue b/packages/@vuepress/theme-default/src/client/components/global/ExternalLinkIcon.vue deleted file mode 100644 index b01897a6ee..0000000000 --- a/packages/@vuepress/theme-default/src/client/components/global/ExternalLinkIcon.vue +++ /dev/null @@ -1,12 +0,0 @@ - - - diff --git a/packages/@vuepress/theme-default/src/node/defaultTheme.ts b/packages/@vuepress/theme-default/src/node/defaultTheme.ts index e789ef752d..d31f950f4e 100644 --- a/packages/@vuepress/theme-default/src/node/defaultTheme.ts +++ b/packages/@vuepress/theme-default/src/node/defaultTheme.ts @@ -108,7 +108,7 @@ export const defaultTheme: Theme = ( '@vuepress/container', resolveContainerPluginOptionsForCodeGroupItem(themePlugins), ], - ['@vuepress/external-link-icon', themePlugins.externalLinkIcon !== false], + ['@vuepress/external-link-icon', themePlugins.externalLinkIcon], ['@vuepress/git', resolveGitPluginOptions(themePlugins, localeOptions)], ['@vuepress/medium-zoom', resolveMediumZoomPluginOptions(themePlugins)], ['@vuepress/nprogress', themePlugins.nprogress !== false], diff --git a/packages/@vuepress/theme-default/src/node/utils/assignDefaultLocaleOptions.ts b/packages/@vuepress/theme-default/src/node/utils/assignDefaultLocaleOptions.ts index ca09f16c8a..5280ddf4ae 100644 --- a/packages/@vuepress/theme-default/src/node/utils/assignDefaultLocaleOptions.ts +++ b/packages/@vuepress/theme-default/src/node/utils/assignDefaultLocaleOptions.ts @@ -34,7 +34,6 @@ export const DEFAULT_LOCALE_OPTIONS: DefaultThemeLocaleOptions = { backToHome: 'Take me home', // a11y - openInNewWindow: 'open in new window', toggleDarkMode: 'toggle dark mode', toggleSidebar: 'toggle sidebar', } diff --git a/packages/@vuepress/theme-default/src/shared/options.ts b/packages/@vuepress/theme-default/src/shared/options.ts index 6e8643cb8d..03c7d88994 100644 --- a/packages/@vuepress/theme-default/src/shared/options.ts +++ b/packages/@vuepress/theme-default/src/shared/options.ts @@ -1,3 +1,4 @@ +import type { ExternalLinkIconPluginOptions } from '@vuepress/plugin-external-link-icon' import type { ThemeData } from '@vuepress/plugin-theme-data' import type { LocaleData } from '@vuepress/shared' import type { NavbarConfig, SidebarConfig } from './nav' @@ -28,7 +29,7 @@ export interface DefaultThemePluginsOptions { /** * Enable @vuepress/plugin-external-link-icon or not */ - externalLinkIcon?: boolean + externalLinkIcon?: ExternalLinkIconPluginOptions | boolean /** * Enable @vuepress/plugin-git or not @@ -260,11 +261,6 @@ export interface DefaultThemeLocaleData extends LocaleData { */ backToHome?: string - /** - * A11y text for external link icon - */ - openInNewWindow?: string - /** * A11y text for dark mode toggle button */ From 19c1f6c3d39425ba58308afa2a9ae59e7db701c1 Mon Sep 17 00:00:00 2001 From: "Mr.Hope" Date: Tue, 18 Jan 2022 16:44:16 +0800 Subject: [PATCH 2/7] fix(plugin-external-link-icon): fix typos and add default value --- .../src/node/externalLinkIconPlugin.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/@vuepress/plugin-external-link-icon/src/node/externalLinkIconPlugin.ts b/packages/@vuepress/plugin-external-link-icon/src/node/externalLinkIconPlugin.ts index 7894020f82..05639338b0 100644 --- a/packages/@vuepress/plugin-external-link-icon/src/node/externalLinkIconPlugin.ts +++ b/packages/@vuepress/plugin-external-link-icon/src/node/externalLinkIconPlugin.ts @@ -14,8 +14,8 @@ export const externalLinkIconPlugin: Plugin = ( ) => ({ name: '@vuepress/plugin-external-link-icon', - alias: { - EXTERNAL_LINK_ICON_I18N: options.i18n, + define: { + EXTERNAL_LINK_ICON_I18N: options.i18n || {}, }, clientAppEnhanceFiles: path.resolve( From 73ce1362921944a72c3ac26d9c35b0a13662ce7d Mon Sep 17 00:00:00 2001 From: "Mr.Hope" Date: Tue, 18 Jan 2022 19:53:25 +0800 Subject: [PATCH 3/7] feat(plugin-external-link-icon): refine locale config --- .../src/client/components/ExternalLinkIcon.ts | 8 ++++++-- .../src/node/externalLinkIconPlugin.ts | 10 ++++++---- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/packages/@vuepress/plugin-external-link-icon/src/client/components/ExternalLinkIcon.ts b/packages/@vuepress/plugin-external-link-icon/src/client/components/ExternalLinkIcon.ts index b54086e158..7b40b3ece8 100644 --- a/packages/@vuepress/plugin-external-link-icon/src/client/components/ExternalLinkIcon.ts +++ b/packages/@vuepress/plugin-external-link-icon/src/client/components/ExternalLinkIcon.ts @@ -1,11 +1,14 @@ import { useRouteLocale } from '@vuepress/client' +import type { LocaleConfig } from '@vuepress/core' import { h } from 'vue' import type { FunctionalComponent } from 'vue' import '../styles/vars.css' import '../styles/external-link-icon.css' -declare const EXTERNAL_LINK_ICON_I18N: Record +declare const EXTERNAL_LINK_ICON_LOCALES: LocaleConfig<{ + openinNewWindow: string +}> const svg = h( 'svg', @@ -40,7 +43,8 @@ export const ExternalLinkIcon: FunctionalComponent = (_, { slots }) => h( 'span', { class: 'external-link-sr-only-text' }, - EXTERNAL_LINK_ICON_I18N[useRouteLocale().value] || 'open in new window' + EXTERNAL_LINK_ICON_LOCALES[useRouteLocale().value].openinNewWindow || + 'open in new window' ), ]) diff --git a/packages/@vuepress/plugin-external-link-icon/src/node/externalLinkIconPlugin.ts b/packages/@vuepress/plugin-external-link-icon/src/node/externalLinkIconPlugin.ts index 05639338b0..5901d18fc8 100644 --- a/packages/@vuepress/plugin-external-link-icon/src/node/externalLinkIconPlugin.ts +++ b/packages/@vuepress/plugin-external-link-icon/src/node/externalLinkIconPlugin.ts @@ -1,12 +1,14 @@ -import type { Plugin } from '@vuepress/core' +import type { LocaleConfig, Plugin } from '@vuepress/core' import type { MarkdownEnv } from '@vuepress/markdown' import { path } from '@vuepress/utils' export type ExternalLinkIconPluginOptions = { /** - * i18n config + * locales config */ - i18n: Record + locales: LocaleConfig<{ + openinNewWindow: string + }> } export const externalLinkIconPlugin: Plugin = ( @@ -15,7 +17,7 @@ export const externalLinkIconPlugin: Plugin = ( name: '@vuepress/plugin-external-link-icon', define: { - EXTERNAL_LINK_ICON_I18N: options.i18n || {}, + EXTERNAL_LINK_ICON_LOCALES: options.locales || {}, }, clientAppEnhanceFiles: path.resolve( From 7249756ff917a16c0fcf7fb2d3096325554b0777 Mon Sep 17 00:00:00 2001 From: meteorlxy Date: Fri, 21 Jan 2022 15:59:05 +0800 Subject: [PATCH 4/7] chore: tweaks --- .../src/client/clientAppEnhance.ts | 8 ++- .../src/client/components/ExternalLinkIcon.ts | 53 ++++++++++++------- .../src/client/styles/external-link-icon.css | 2 +- .../src/node/externalLinkIconPlugin.ts | 21 ++++---- .../src/shared/index.ts | 1 + .../src/shared/types.ts | 5 ++ .../tsconfig.cjs.json | 2 +- .../tsconfig.esm.json | 2 +- .../src/client/styles/index.scss | 1 - .../src/client/styles/sr-only.scss | 12 ----- .../theme-default/src/node/defaultTheme.ts | 6 ++- .../theme-default/src/node/utils/index.ts | 1 + .../resolveExternalLinkIconPluginOptions.ts | 27 ++++++++++ .../theme-default/src/shared/options.ts | 8 ++- 14 files changed, 99 insertions(+), 50 deletions(-) create mode 100644 packages/@vuepress/plugin-external-link-icon/src/shared/index.ts create mode 100644 packages/@vuepress/plugin-external-link-icon/src/shared/types.ts delete mode 100644 packages/@vuepress/theme-default/src/client/styles/sr-only.scss create mode 100644 packages/@vuepress/theme-default/src/node/utils/resolveExternalLinkIconPluginOptions.ts diff --git a/packages/@vuepress/plugin-external-link-icon/src/client/clientAppEnhance.ts b/packages/@vuepress/plugin-external-link-icon/src/client/clientAppEnhance.ts index 504bb1716e..b61d127f85 100644 --- a/packages/@vuepress/plugin-external-link-icon/src/client/clientAppEnhance.ts +++ b/packages/@vuepress/plugin-external-link-icon/src/client/clientAppEnhance.ts @@ -1,6 +1,12 @@ import { defineClientAppEnhance } from '@vuepress/client' +import { h } from 'vue' +import type { ExternalLinkIconLocales } from '../shared' import { ExternalLinkIcon } from './components/ExternalLinkIcon' +declare const __EXTERNAL_LINK_ICON_LOCALES__: ExternalLinkIconLocales + +const locales = __EXTERNAL_LINK_ICON_LOCALES__ + export default defineClientAppEnhance(({ app }) => { - app.component('ExternalLinkIcon', ExternalLinkIcon) + app.component('ExternalLinkIcon', h(ExternalLinkIcon, { locales })) }) diff --git a/packages/@vuepress/plugin-external-link-icon/src/client/components/ExternalLinkIcon.ts b/packages/@vuepress/plugin-external-link-icon/src/client/components/ExternalLinkIcon.ts index 7b40b3ece8..4f32708a77 100644 --- a/packages/@vuepress/plugin-external-link-icon/src/client/components/ExternalLinkIcon.ts +++ b/packages/@vuepress/plugin-external-link-icon/src/client/components/ExternalLinkIcon.ts @@ -1,15 +1,11 @@ import { useRouteLocale } from '@vuepress/client' -import type { LocaleConfig } from '@vuepress/core' -import { h } from 'vue' -import type { FunctionalComponent } from 'vue' +import type { PropType } from 'vue' +import { computed, defineComponent, h } from 'vue' +import type { ExternalLinkIconLocales } from '../../shared' import '../styles/vars.css' import '../styles/external-link-icon.css' -declare const EXTERNAL_LINK_ICON_LOCALES: LocaleConfig<{ - openinNewWindow: string -}> - const svg = h( 'svg', { @@ -36,16 +32,35 @@ const svg = h( ] ) -export const ExternalLinkIcon: FunctionalComponent = (_, { slots }) => - h('span', [ - svg, - slots.default?.() || - h( - 'span', - { class: 'external-link-sr-only-text' }, - EXTERNAL_LINK_ICON_LOCALES[useRouteLocale().value].openinNewWindow || - 'open in new window' - ), - ]) +export const ExternalLinkIcon = defineComponent({ + name: 'ExternalLinkIcon', + + props: { + locales: { + type: Object as PropType, + required: false, + default: () => ({}), + }, + }, -ExternalLinkIcon.displayName = 'ExternalLinkIcon' + setup(props) { + const routeLocale = useRouteLocale() + const locale = computed( + () => + props.locales[routeLocale.value] ?? { + openInNewWindow: 'open in new window', + } + ) + return () => + h('span', [ + svg, + h( + 'span', + { + class: 'external-link-icon-sr-only', + }, + locale.value.openInNewWindow + ), + ]) + }, +}) diff --git a/packages/@vuepress/plugin-external-link-icon/src/client/styles/external-link-icon.css b/packages/@vuepress/plugin-external-link-icon/src/client/styles/external-link-icon.css index 9ac51bdf61..3343aee5d5 100644 --- a/packages/@vuepress/plugin-external-link-icon/src/client/styles/external-link-icon.css +++ b/packages/@vuepress/plugin-external-link-icon/src/client/styles/external-link-icon.css @@ -6,7 +6,7 @@ top: -1px; } -.external-link-sr-only-text { +.external-link-icon-sr-only { position: absolute; width: 1px; height: 1px; diff --git a/packages/@vuepress/plugin-external-link-icon/src/node/externalLinkIconPlugin.ts b/packages/@vuepress/plugin-external-link-icon/src/node/externalLinkIconPlugin.ts index 5901d18fc8..e4a86a60ba 100644 --- a/packages/@vuepress/plugin-external-link-icon/src/node/externalLinkIconPlugin.ts +++ b/packages/@vuepress/plugin-external-link-icon/src/node/externalLinkIconPlugin.ts @@ -1,23 +1,22 @@ -import type { LocaleConfig, Plugin } from '@vuepress/core' +import type { Plugin } from '@vuepress/core' import type { MarkdownEnv } from '@vuepress/markdown' import { path } from '@vuepress/utils' +import type { ExternalLinkIconLocales } from '../shared' +/** + * Options for @vuepress/plugin-external-link-icon + */ export type ExternalLinkIconPluginOptions = { - /** - * locales config - */ - locales: LocaleConfig<{ - openinNewWindow: string - }> + locales?: ExternalLinkIconLocales } -export const externalLinkIconPlugin: Plugin = ( - options -) => ({ +export const externalLinkIconPlugin: Plugin = ({ + locales = {}, +}) => ({ name: '@vuepress/plugin-external-link-icon', define: { - EXTERNAL_LINK_ICON_LOCALES: options.locales || {}, + __EXTERNAL_LINK_ICON_LOCALES__: locales, }, clientAppEnhanceFiles: path.resolve( diff --git a/packages/@vuepress/plugin-external-link-icon/src/shared/index.ts b/packages/@vuepress/plugin-external-link-icon/src/shared/index.ts new file mode 100644 index 0000000000..c9f6f047dc --- /dev/null +++ b/packages/@vuepress/plugin-external-link-icon/src/shared/index.ts @@ -0,0 +1 @@ +export * from './types' diff --git a/packages/@vuepress/plugin-external-link-icon/src/shared/types.ts b/packages/@vuepress/plugin-external-link-icon/src/shared/types.ts new file mode 100644 index 0000000000..d1d214bcb2 --- /dev/null +++ b/packages/@vuepress/plugin-external-link-icon/src/shared/types.ts @@ -0,0 +1,5 @@ +import type { LocaleConfig } from '@vuepress/shared' + +export type ExternalLinkIconLocales = LocaleConfig<{ + openInNewWindow: string +}> diff --git a/packages/@vuepress/plugin-external-link-icon/tsconfig.cjs.json b/packages/@vuepress/plugin-external-link-icon/tsconfig.cjs.json index 8ae90821dc..bcb0719155 100644 --- a/packages/@vuepress/plugin-external-link-icon/tsconfig.cjs.json +++ b/packages/@vuepress/plugin-external-link-icon/tsconfig.cjs.json @@ -5,5 +5,5 @@ "rootDir": "./src", "outDir": "./lib" }, - "include": ["./src/node"] + "include": ["./src/node", "./src/shared"] } diff --git a/packages/@vuepress/plugin-external-link-icon/tsconfig.esm.json b/packages/@vuepress/plugin-external-link-icon/tsconfig.esm.json index 91cd8e8620..98610e4b94 100644 --- a/packages/@vuepress/plugin-external-link-icon/tsconfig.esm.json +++ b/packages/@vuepress/plugin-external-link-icon/tsconfig.esm.json @@ -5,5 +5,5 @@ "rootDir": "./src", "outDir": "./lib" }, - "include": ["./src/client"] + "include": ["./src/client", "./src/shared"] } diff --git a/packages/@vuepress/theme-default/src/client/styles/index.scss b/packages/@vuepress/theme-default/src/client/styles/index.scss index 5e3046926a..7ee77d3a6e 100644 --- a/packages/@vuepress/theme-default/src/client/styles/index.scss +++ b/packages/@vuepress/theme-default/src/client/styles/index.scss @@ -13,7 +13,6 @@ @use 'navbar-dropdown'; @use 'page'; @use 'sidebar'; -@use 'sr-only'; @use 'toc'; @use 'transitions'; diff --git a/packages/@vuepress/theme-default/src/client/styles/sr-only.scss b/packages/@vuepress/theme-default/src/client/styles/sr-only.scss deleted file mode 100644 index 33e25b30eb..0000000000 --- a/packages/@vuepress/theme-default/src/client/styles/sr-only.scss +++ /dev/null @@ -1,12 +0,0 @@ -.sr-only { - position: absolute; - width: 1px; - height: 1px; - padding: 0; - margin: -1px; - overflow: hidden; - clip: rect(0, 0, 0, 0); - white-space: nowrap; - border-width: 0; - user-select: none; -} diff --git a/packages/@vuepress/theme-default/src/node/defaultTheme.ts b/packages/@vuepress/theme-default/src/node/defaultTheme.ts index d31f950f4e..df6312a24f 100644 --- a/packages/@vuepress/theme-default/src/node/defaultTheme.ts +++ b/packages/@vuepress/theme-default/src/node/defaultTheme.ts @@ -12,6 +12,7 @@ import { resolveContainerPluginOptionsForCodeGroup, resolveContainerPluginOptionsForCodeGroupItem, resolveContainerPluginOptionsForDetails, + resolveExternalLinkIconPluginOptions, resolveGitPluginOptions, resolveMediumZoomPluginOptions, } from './utils' @@ -108,7 +109,10 @@ export const defaultTheme: Theme = ( '@vuepress/container', resolveContainerPluginOptionsForCodeGroupItem(themePlugins), ], - ['@vuepress/external-link-icon', themePlugins.externalLinkIcon], + [ + '@vuepress/external-link-icon', + resolveExternalLinkIconPluginOptions(themePlugins, localeOptions), + ], ['@vuepress/git', resolveGitPluginOptions(themePlugins, localeOptions)], ['@vuepress/medium-zoom', resolveMediumZoomPluginOptions(themePlugins)], ['@vuepress/nprogress', themePlugins.nprogress !== false], diff --git a/packages/@vuepress/theme-default/src/node/utils/index.ts b/packages/@vuepress/theme-default/src/node/utils/index.ts index 17cd5b4e68..9e8de92dd5 100644 --- a/packages/@vuepress/theme-default/src/node/utils/index.ts +++ b/packages/@vuepress/theme-default/src/node/utils/index.ts @@ -1,5 +1,6 @@ export * from './assignDefaultLocaleOptions' export * from './resolveActiveHeaderLinksPluginOptions' export * from './resolveContainerPluginOptions' +export * from './resolveExternalLinkIconPluginOptions' export * from './resolveGitPluginOptions' export * from './resolveMediumZoomPluginOptions' diff --git a/packages/@vuepress/theme-default/src/node/utils/resolveExternalLinkIconPluginOptions.ts b/packages/@vuepress/theme-default/src/node/utils/resolveExternalLinkIconPluginOptions.ts new file mode 100644 index 0000000000..18304a889b --- /dev/null +++ b/packages/@vuepress/theme-default/src/node/utils/resolveExternalLinkIconPluginOptions.ts @@ -0,0 +1,27 @@ +import type { ExternalLinkIconPluginOptions } from '@vuepress/plugin-external-link-icon' +import type { DefaultThemeData, DefaultThemePluginsOptions } from '../../shared' + +/** + * Resolve options for @vuepress/plugin-external-link-icon + */ +export const resolveExternalLinkIconPluginOptions = ( + themePlugins: DefaultThemePluginsOptions, + localeOptions: DefaultThemeData +): ExternalLinkIconPluginOptions | boolean => { + if (themePlugins?.externalLinkIcon === false) { + return false + } + + return { + locales: Object.entries(localeOptions.locales || {}).reduce( + (result, [key, value]) => { + result[key] = { + openInNewWindow: + value.openInNewWindow ?? localeOptions.openInNewWindow, + } + return result + }, + {} + ), + } +} diff --git a/packages/@vuepress/theme-default/src/shared/options.ts b/packages/@vuepress/theme-default/src/shared/options.ts index 03c7d88994..6e8643cb8d 100644 --- a/packages/@vuepress/theme-default/src/shared/options.ts +++ b/packages/@vuepress/theme-default/src/shared/options.ts @@ -1,4 +1,3 @@ -import type { ExternalLinkIconPluginOptions } from '@vuepress/plugin-external-link-icon' import type { ThemeData } from '@vuepress/plugin-theme-data' import type { LocaleData } from '@vuepress/shared' import type { NavbarConfig, SidebarConfig } from './nav' @@ -29,7 +28,7 @@ export interface DefaultThemePluginsOptions { /** * Enable @vuepress/plugin-external-link-icon or not */ - externalLinkIcon?: ExternalLinkIconPluginOptions | boolean + externalLinkIcon?: boolean /** * Enable @vuepress/plugin-git or not @@ -261,6 +260,11 @@ export interface DefaultThemeLocaleData extends LocaleData { */ backToHome?: string + /** + * A11y text for external link icon + */ + openInNewWindow?: string + /** * A11y text for dark mode toggle button */ From 619e491ac4b7f0438d4e3fe5e54565398a40cbbe Mon Sep 17 00:00:00 2001 From: meteorlxy Date: Fri, 21 Jan 2022 16:00:54 +0800 Subject: [PATCH 5/7] chore: tweaks --- docs/.vuepress/config.ts | 7 +------ .../@vuepress/client/__tests__/__fixtures__/siteData.ts | 2 ++ .../src/node/utils/assignDefaultLocaleOptions.ts | 1 + 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/docs/.vuepress/config.ts b/docs/.vuepress/config.ts index 86fa67f191..d0f7e92c0f 100644 --- a/docs/.vuepress/config.ts +++ b/docs/.vuepress/config.ts @@ -129,18 +129,13 @@ export default defineUserConfig({ backToHome: '返回首页', // a11y + openInNewWindow: '在新窗口打开', toggleDarkMode: '切换夜间模式', toggleSidebar: '切换侧边栏', }, }, themePlugins: { - externalLinkIcon: { - i18n: { - '/zh/': '在新窗口打开', - }, - }, - // only enable git plugin in production mode git: isProd, }, diff --git a/packages/@vuepress/client/__tests__/__fixtures__/siteData.ts b/packages/@vuepress/client/__tests__/__fixtures__/siteData.ts index 9cb270e95c..534520e6c8 100644 --- a/packages/@vuepress/client/__tests__/__fixtures__/siteData.ts +++ b/packages/@vuepress/client/__tests__/__fixtures__/siteData.ts @@ -29,6 +29,7 @@ export const siteData = { "Looks like we've got some broken links.", ], backToHome: 'Take me home', + openInNewWindow: 'open in new window', }, '/zh/': { info: '提示', @@ -41,6 +42,7 @@ export const siteData = { '看起来我们进入了错误的链接', ], backToHome: '返回首页', + openInNewWindow: '在新窗口打开', }, }, }, diff --git a/packages/@vuepress/theme-default/src/node/utils/assignDefaultLocaleOptions.ts b/packages/@vuepress/theme-default/src/node/utils/assignDefaultLocaleOptions.ts index 5280ddf4ae..ca09f16c8a 100644 --- a/packages/@vuepress/theme-default/src/node/utils/assignDefaultLocaleOptions.ts +++ b/packages/@vuepress/theme-default/src/node/utils/assignDefaultLocaleOptions.ts @@ -34,6 +34,7 @@ export const DEFAULT_LOCALE_OPTIONS: DefaultThemeLocaleOptions = { backToHome: 'Take me home', // a11y + openInNewWindow: 'open in new window', toggleDarkMode: 'toggle dark mode', toggleSidebar: 'toggle sidebar', } From e9c33dd5d10b1a8e2eacfd58eadd6c84a754d4bf Mon Sep 17 00:00:00 2001 From: meteorlxy Date: Fri, 21 Jan 2022 16:08:52 +0800 Subject: [PATCH 6/7] chore: add docs --- docs/reference/plugin/external-link-icon.md | 37 +++++++++++++++++++ .../zh/reference/plugin/external-link-icon.md | 37 +++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/docs/reference/plugin/external-link-icon.md b/docs/reference/plugin/external-link-icon.md index 1918cb47ae..d7435abfd1 100644 --- a/docs/reference/plugin/external-link-icon.md +++ b/docs/reference/plugin/external-link-icon.md @@ -12,6 +12,43 @@ This plugin has been integrated into the default theme. npm i -D @vuepress/plugin-external-link-icon@next ``` +## Options + +### locales + +- Type: `Record` + +- Details: + + The a11y text of the external link icon in different locales. + + If this option is not specified, it will fallback to default text. + +- Example: + +```js +module.exports = { + plugins: [ + [ + '@vuepress/plugin-external-link-icon', + { + locales: { + '/': { + openInNewWindow: 'open in new window', + }, + '/zh/': { + openInNewWindow: '在新窗口打开', + }, + }, + }, + ], + ], +} +``` + +- Also see: + - [Guide > I18n](../../guide/i18n.md) + ## Frontmatter ### externalLinkIcon diff --git a/docs/zh/reference/plugin/external-link-icon.md b/docs/zh/reference/plugin/external-link-icon.md index 508d2e4022..c75b9db1b5 100644 --- a/docs/zh/reference/plugin/external-link-icon.md +++ b/docs/zh/reference/plugin/external-link-icon.md @@ -12,6 +12,43 @@ npm i -D @vuepress/plugin-external-link-icon@next ``` +## 配置项 + +### locales + +- 类型: `Record` + +- 详情: + + 外部链接图标在不同 locales 下的 A11y 文字。 + + 如果没有指定该配置项,它会降级使用默认文字。 + +- 示例: + +```js +module.exports = { + plugins: [ + [ + '@vuepress/plugin-external-link-icon', + { + locales: { + '/': { + openInNewWindow: 'open in new window', + }, + '/zh/': { + openInNewWindow: '在新窗口打开', + }, + }, + }, + ], + ], +} +``` + +- 参考: + - [指南 > 多语言支持](../../guide/i18n.md) + ## Frontmatter ### externalLinkIcon From 812826e6540a7032bb1bb323dd54c6e10b2d4649 Mon Sep 17 00:00:00 2001 From: meteorlxy Date: Fri, 21 Jan 2022 16:17:21 +0800 Subject: [PATCH 7/7] chore: tweaks --- .../plugin-external-link-icon/src/client/clientAppEnhance.ts | 1 + .../src/client/components/ExternalLinkIcon.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/@vuepress/plugin-external-link-icon/src/client/clientAppEnhance.ts b/packages/@vuepress/plugin-external-link-icon/src/client/clientAppEnhance.ts index b61d127f85..42eb611f99 100644 --- a/packages/@vuepress/plugin-external-link-icon/src/client/clientAppEnhance.ts +++ b/packages/@vuepress/plugin-external-link-icon/src/client/clientAppEnhance.ts @@ -8,5 +8,6 @@ declare const __EXTERNAL_LINK_ICON_LOCALES__: ExternalLinkIconLocales const locales = __EXTERNAL_LINK_ICON_LOCALES__ export default defineClientAppEnhance(({ app }) => { + // wrap the `` component with plugin options app.component('ExternalLinkIcon', h(ExternalLinkIcon, { locales })) }) diff --git a/packages/@vuepress/plugin-external-link-icon/src/client/components/ExternalLinkIcon.ts b/packages/@vuepress/plugin-external-link-icon/src/client/components/ExternalLinkIcon.ts index 4f32708a77..8ffbff59f2 100644 --- a/packages/@vuepress/plugin-external-link-icon/src/client/components/ExternalLinkIcon.ts +++ b/packages/@vuepress/plugin-external-link-icon/src/client/components/ExternalLinkIcon.ts @@ -1,6 +1,6 @@ import { useRouteLocale } from '@vuepress/client' -import type { PropType } from 'vue' import { computed, defineComponent, h } from 'vue' +import type { PropType } from 'vue' import type { ExternalLinkIconLocales } from '../../shared' import '../styles/vars.css'