feat(plugin-md-power): improve caniuse syntax (#806)

This commit is contained in:
pengzhanbo 2025-12-28 14:00:53 +08:00 committed by GitHub
parent 2bcf761ef1
commit fe9ee0dbfc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 94 additions and 123 deletions

View File

@ -35,7 +35,7 @@ const locale = computed(() => LOCALES[routeLocale.value])
const { feature, featureList, onSelect, isFocus } = useCaniuseFeaturesSearch(inputEl, listEl)
const { past, pastList, future, futureList, embedType, embedTypeList } = useCaniuseVersionSelect()
const { output, rendered } = useCaniuse({ feature, embedType, past, future })
const { output } = useCaniuse({ feature, embedType, past, future })
</script>
<template>
@ -63,9 +63,8 @@ const { output, rendered } = useCaniuse({ feature, embedType, past, future })
class="feature-list-item"
@click="onSelect(item)"
@keydown.enter="onSelect(item)"
>
{{ item.label }}
</button>
v-html="item.label"
/>
</li>
</ul>
</div>
@ -80,7 +79,6 @@ const { output, rendered } = useCaniuse({ feature, embedType, past, future })
>
<input :id="`caniuse-embed-${id}-${index}`" v-model="embedType" type="radio" name="embedType" :value="item.value">
<span>{{ item.label }}</span>
<Badge v-if="item.value === 'image'" type="warning" :text="locale['no-recommend']" />
</label>
</div>
</div>
@ -109,8 +107,7 @@ const { output, rendered } = useCaniuse({ feature, embedType, past, future })
<h4>{{ locale.output }}</h4>
<CodeViewer lang="md" :content="output" />
</div>
<div v-if="embedType === 'image'" v-html="rendered" />
<CanIUseViewer v-else-if="feature" :feature="feature" :past="past" :future="future" />
<CanIUseViewer v-if="feature" :feature="feature" :past="past" :future="future" :baseline="embedType === 'baseline'" />
</div>
</template>

View File

@ -34,8 +34,8 @@ const locales: LocaleConfig<
}
const embedTypes: SelectItem[] = [
{ label: 'iframe', value: '' },
{ label: 'image', value: 'image' },
{ label: 'caniuse', value: '' },
{ label: 'baseline', value: 'baseline' },
]
export function useCaniuseVersionSelect(): {
@ -159,19 +159,20 @@ export function useCaniuse({ feature, embedType, past, future }: {
future: Ref<string>
}): {
output: ComputedRef<string>
rendered: ComputedRef<string>
} {
const output = computed(() => {
let content = '@[caniuse'
if (embedType.value)
content += ` ${embedType.value}`
if (embedType.value !== 'baseline') {
if (past.value !== '-2' || future.value !== '1') {
if (past.value === '0' && future.value === '0')
content += '{0}'
else
content += `{-${past.value},${future.value}}`
}
}
content += ']('
@ -181,21 +182,5 @@ export function useCaniuse({ feature, embedType, past, future }: {
return `${content})`
})
const rendered = computed(() => {
if (!feature.value || !embedType.value)
return ''
return resolveCanIUse(feature.value)
})
return { output, rendered }
}
function resolveCanIUse(feature: string): string {
const link = 'https://caniuse.bitsofco.de/image/'
const alt = `Data on support for the ${feature} feature across the major browsers from caniuse.com`
return `<p><picture>
<source type="image/webp" srcset="${link}${feature}.webp">
<source type="image/png" srcset="${link}${feature}.png">
<img src="${link}${feature}.jpg" alt="${alt}" width="100%">
</picture></p>`
return { output }
}

View File

@ -3,6 +3,7 @@ title: Can I Use
createTime: 2025/10/08 14:50:55
icon: streamline:desktop-help
permalink: /en/guide/markdown/caniuse/
badge: New
---
## Overview
@ -43,36 +44,39 @@ You can use this tool directly to help generate the markdown code.
@[caniuse embed_type{browser_versions}](feature)
```
:::info Using the caniuse tool provided by the theme: [caniuse feature search](../../../../tools/caniuse.md) to help generate markdown code.
:::
- `feature`
Required. For correct values, please refer to [caniuse-embed.vercel.app](https://caniuse-embed.vercel.app/zh-CN).
- `{browser_versions}`
- `{browser_period}`
Optional. Specifies the support status of the current feature across multiple browser versions.
Optional. The support status of the current feature across multiple version cycles.
Default value: `{-2,1}`
Format: `{past,future}` Value range: `-5 ~ 3`
Format: `{past,future}` with a value range of `-5 ~ 3`
- Values less than `0` indicate support status for browser versions lower than the current one.
- `0` indicates the support status for the current browser version.
- Values greater than `0` indicate support status for browser versions higher than the current one.
- Values less than `0` indicate support status in past browser version cycles.
- `0` indicates support status in the current browser version.
- Values greater than `0` indicate support status in future browser version cycles.
- `embed_type`
Optional. The type of resource embedding.
Type: `'embed' | 'image'`
Type: `'embed' | 'baseline'`
Default value: `'embed'`
:::caution
The `image` type is no longer recommended. It is advised to use the `embed` type.
The theme has changed the implementation technology for the embed component.
The current `embed` type now offers significant advantages over the `image` type,
including faster loading speed, smaller size, and better interactive experience.
:::
- `embed` means embedding as version compatibility data tables similar to `caniuse.com`
- `baseline` means embedding as the baseline support status of a feature.
- `Wildly available` indicates broad support across all major browsers
- `Newly available` indicates support only in the latest major browsers
- `limit available` indicates that major browsers may offer partial support, but it is limited, or not supported
- `deprecated` indicates that major browsers have marked it as **deprecated** and do not recommend its use
## Examples
@ -86,22 +90,12 @@ Result:
@[caniuse](css-matches-pseudo)
**Get the browser support for the CSS pseudo-class selector `:dir()` as an image:**
**Display baseline support for the CSS pseudo-class selector `:dir()`:**
```md
@[caniuse image](css-matches-pseudo)
@[caniuse baseline](css-matches-pseudo)
```
Result:
@[caniuse image](css-matches-pseudo)
**Get the browser support for the CSS pseudo-class selector `:dir()` for a specific range of browser versions:**
```md
@[caniuse{-2,3}](css-matches-pseudo)
```
Result:
@[caniuse{-2,3}](css-matches-pseudo)
@[caniuse baseline](css-matches-pseudo)

View File

@ -3,6 +3,7 @@ title: Can I Use
createTime: 2024/09/30 14:50:55
icon: streamline:desktop-help
permalink: /guide/markdown/caniuse/
badge: 新
---
## 概述
@ -43,34 +44,39 @@ export default defineUserConfig({
@[caniuse embed_type{browser_versions}](feature)
```
:::info 使用主题提供的 caniuse 工具:[caniuse 特性搜索](../../../tools/caniuse.md) 帮助生成 markdown 代码。
:::
- `feature`
必填。 正确取值请参考 [caniuse-embed.vercel.app](https://caniuse-embed.vercel.app/zh-CN)
- `{browser_versions}`
- `{browser_period}`
可选。当前特性在多个版本中的支持情况。
可选。当前特性在多个版本周期中的支持情况。
默认值为: `{-2,1}`
格式: `{past,future}` 取值范围为 `-5 ~ 3`
- 小于`0` 表示低于当前浏览器版本的支持情况
- 小于`0` 表示过去的浏览器版本周期的支持情况
- `0` 表示当前浏览器版本的支持情况
- 大于`0` 表示高于当前浏览器版本的支持情况
- 大于`0` 表示未来的浏览器版本周期的支持情况
- `embed_type`
可选。 资源嵌入的类型。
可选。 嵌入的类型。
类型: `'embed' | 'image'`
类型: `'embed' | 'baseline'`
默认值为:`'embed'`
:::caution
不再推荐使用 image 类型,建议使用 embed 类型,主题更换了 embed 实现技术方案,
现在的 embed 类型优势已远远超过 image 类型,加载速度更快,体积更小,交互体验更好。
:::
- `embed` 表示嵌入为 类似 `caniuse.com` 的版本兼容数据表格
- `baseline` 表示嵌入为 特性的基线支持情况。
- `Wildly available` 表示受到所有主流浏览器的广泛支持
- `Newly available` 表示仅受到最新主流浏览器的支持
- `limit available` 表示主流浏览器可能部分支持,但支持程度有限,或者不支持
- `deprecated` 表示主流浏览器已将其标记为 **弃用**,不推荐使用
## 示例
@ -84,22 +90,12 @@ export default defineUserConfig({
@[caniuse](css-matches-pseudo)
**以图片的形式,获取 css 伪类选择器 `:dir()` 在各个浏览器的支持情况:**
**显示 css 伪类选择器 `:dir()` 的基线支持情况:**
```md
@[caniuse image](css-matches-pseudo)
@[caniuse baseline](css-matches-pseudo)
```
效果:
@[caniuse image](css-matches-pseudo)
**获取 css 伪类选择器 `:dir()` 特定范围浏览器的支持情况:**
```md
@[caniuse{-2,3}](css-matches-pseudo)
```
效果:
@[caniuse{-2,3}](css-matches-pseudo)
@[caniuse baseline](css-matches-pseudo)

View File

@ -39,13 +39,7 @@ exports[`caniusePlugin > should not work 8`] = `
exports[`caniusePlugin > should work 1`] = `"<CanIUseViewer feature="feature" meta="test-id" :past="2" :future="1" />"`;
exports[`caniusePlugin > should work 2`] = `
"<ClientOnly><p><picture>
<source type="image/webp" srcset="https://caniuse.bitsofco.de/image/feature.webp">
<source type="image/png" srcset="https://caniuse.bitsofco.de/image/feature.png">
<img src="https://caniuse.bitsofco.de/image/feature.jpg" alt="Data on support for the feature feature across the major browsers from caniuse.com" width="100%">
</picture></p></ClientOnly>"
`;
exports[`caniusePlugin > should work 2`] = `"<CanIUseViewer feature="feature" meta="test-id" :past="2" :future="1" baseline />"`;
exports[`caniusePlugin > should work 3`] = `"<CanIUseViewer feature="feature" meta="test-id" :past="2" :future="1" />"`;
@ -55,13 +49,7 @@ exports[`caniusePlugin > should work 5`] = `"<CanIUseViewer feature="feature" me
exports[`caniusePlugin > should work 6`] = `"<CanIUseViewer feature="feature" meta="test-id" :past="2" :future="0" />"`;
exports[`caniusePlugin > should work with options 1`] = `
"<ClientOnly><p><picture>
<source type="image/webp" srcset="https://caniuse.bitsofco.de/image/feature.webp">
<source type="image/png" srcset="https://caniuse.bitsofco.de/image/feature.png">
<img src="https://caniuse.bitsofco.de/image/feature.jpg" alt="Data on support for the feature feature across the major browsers from caniuse.com" width="100%">
</picture></p></ClientOnly>"
`;
exports[`caniusePlugin > should work with options 1`] = `"<CanIUseViewer feature="feature" meta="test-id" :past="2" :future="1" baseline />"`;
exports[`caniusePlugin > should work with options 2`] = `"<CanIUseViewer feature="feature" meta="test-id" :past="2" :future="1" />"`;
@ -74,17 +62,17 @@ exports[`legacyCaniuse > should work 2`] = `"<CanIUseViewer feature="feature{-2,
exports[`legacyCaniuse > should work 3`] = `""`;
exports[`legacyCaniuse > should work with unknown mode 1`] = `
"<ClientOnly><p><picture>
"<p><picture>
<source type="image/webp" srcset="https://caniuse.bitsofco.de/image/feature.webp">
<source type="image/png" srcset="https://caniuse.bitsofco.de/image/feature.png">
<img src="https://caniuse.bitsofco.de/image/feature.jpg" alt="Data on support for the feature feature across the major browsers from caniuse.com" width="100%">
</picture></p></ClientOnly>"
</picture></p>"
`;
exports[`legacyCaniuse > should work with unknown mode 2`] = `
"<ClientOnly><p><picture>
"<p><picture>
<source type="image/webp" srcset="https://caniuse.bitsofco.de/image/feature{-2,4}.webp">
<source type="image/png" srcset="https://caniuse.bitsofco.de/image/feature{-2,4}.png">
<img src="https://caniuse.bitsofco.de/image/feature{-2,4}.jpg" alt="Data on support for the feature{-2,4} feature across the major browsers from caniuse.com" width="100%">
</picture></p></ClientOnly>"
</picture></p>"
`;

View File

@ -21,7 +21,7 @@ describe('caniusePlugin', () => {
const md = createMarkdown()
expect(md.render('@[caniuse](feature)')).toMatchSnapshot()
expect(md.render('@[caniuse image](feature)')).toMatchSnapshot()
expect(md.render('@[caniuse baseline](feature)')).toMatchSnapshot()
expect(md.render('@[caniuse embed](feature)')).toMatchSnapshot()
expect(md.render('@[caniuse {-2,4}](feature)')).toMatchSnapshot()
expect(md.render(`\
@ -32,7 +32,7 @@ describe('caniusePlugin', () => {
})
it('should work with options', () => {
const md = createMarkdown({ mode: 'image' })
const md = createMarkdown({ mode: 'baseline' })
expect(md.render('@[caniuse](feature)')).toMatchSnapshot()
expect(md.render('@[caniuse embed](feature)')).toMatchSnapshot()

View File

@ -12,20 +12,21 @@ interface MessageData {
}
}
const { feature, past = 2, future = 1, meta = '' } = defineProps<{
const { feature, past = 2, future = 1, meta = '', baseline = false } = defineProps<{
feature: string
past?: number
future?: number
meta?: string
baseline?: boolean
}>()
const url = 'https://caniuse.pengzhanbo.cn/'
const height = ref('330px')
const height = ref(baseline ? '150px' : '350px')
const isDark = useDarkMode()
const source = computed(() => {
const source = `${url}${feature}#past=${past}&future=${future}&meta=${meta}&theme=${isDark.value ? 'dark' : 'light'}`
const source = `${url}${feature}${baseline ? '/baseline#' : `#past=${past}&future=${future}&`}meta=${meta}&theme=${isDark.value ? 'dark' : 'light'}`
return source
})
@ -34,7 +35,7 @@ useEventListener('message', (event) => {
const data = parseData(event.data)
const { type, payload } = data
if (
type === 'ciu_embed'
type === 'ciu-embed'
&& payload
&& payload.feature === feature
&& payload.meta === meta
@ -57,13 +58,7 @@ function parseData(data: string | MessageData): MessageData {
</script>
<template>
<div
class="ciu_embed"
:data-feature="feature"
:data-meta="meta"
:data-past="past"
:data-future="future"
>
<div class="ciu_embed" :class="{ baseline }">
<iframe :src="source" :style="{ height }" :title="`Can I use ${feature}`" />
</div>
</template>
@ -73,6 +68,11 @@ function parseData(data: string | MessageData): MessageData {
margin: 16px -24px;
}
.ciu_embed.baseline {
overflow: hidden;
border-radius: 8px;
}
.ciu_embed iframe {
width: 100%;
border: none;

View File

@ -1,11 +1,15 @@
/**
* @[caniuse embed{-2,4}](feature_name)
* @[caniuse image](feature_name)
* @[caniuse baseline](feature_name)
* @[caniuse image](feature_name) // 弃用
*/
import type { PluginWithOptions } from 'markdown-it'
import type MarkdownIt from 'markdown-it'
import type { MarkdownEnv } from 'vuepress/markdown'
import type { CanIUseMode, CanIUseOptions, CanIUseTokenMeta } from '../../shared/index.js'
import { colors } from 'vuepress/utils'
import { createContainerPlugin } from '../container/createContainer.js'
import { logger } from '../utils/logger.js'
import { nanoid } from '../utils/nanoid.js'
import { stringifyAttrs } from '../utils/stringifyAttrs.js'
import { createEmbedRuleBlock } from './createEmbedRuleBlock.js'
@ -23,13 +27,13 @@ export const caniusePlugin: PluginWithOptions<CanIUseOptions> = (
): void => {
createEmbedRuleBlock<CanIUseTokenMeta>(md, {
type: 'caniuse',
syntaxPattern: /^@\[caniuse\s*(embed|image)?(?:\{([0-9,\-]*)\})?\]\(([^)]*)\)/,
syntaxPattern: /^@\[caniuse\s*(embed|image|baseline)?(?:\{([0-9,\-]*)\})?\]\(([^)]*)\)/,
meta: ([, mode, versions = '', feature]) => ({
feature,
mode: (mode as CanIUseMode) || defaultMode,
versions,
}),
content: meta => resolveCanIUse(meta),
content: (meta, _c, env) => resolveCanIUse(meta, env),
})
}
@ -47,39 +51,42 @@ export function legacyCaniuse(
md: MarkdownIt,
{ mode = 'embed' }: CanIUseOptions = {},
): void {
const modeMap: CanIUseMode[] = ['image', 'embed']
const modeMap: CanIUseMode[] = ['image', 'embed', 'baseline']
const isMode = (mode: CanIUseMode): boolean => modeMap.includes(mode)
mode = isMode(mode) ? mode : modeMap[0]
createContainerPlugin(md, 'caniuse', {
before: (info) => {
before: (info, _t, _i, _o, env) => {
const feature = info.split(/\s+/)[0]
const versions = info.match(/\{(.*)\}/)?.[1] || ''
return feature ? resolveCanIUse({ feature, mode, versions }) : ''
return feature ? resolveCanIUse({ feature, mode, versions }, env) : ''
},
after: () => '',
})
}
function resolveCanIUse({ feature, mode, versions }: CanIUseTokenMeta): string {
function resolveCanIUse({ feature, mode, versions }: CanIUseTokenMeta, env: MarkdownEnv): string {
if (!feature)
return ''
if (mode === 'image') {
logger.warn(`[caniuse] image mode is deprecated, use ${
colors.cyan(`@[caniuse](${feature})`)
} instead. (${colors.gray(env.filePathRelative || '')})`)
const link = 'https://caniuse.bitsofco.de/image/'
const alt = `Data on support for the ${feature} feature across the major browsers from caniuse.com`
return `<ClientOnly><p><picture>
return `<p><picture>
<source type="image/webp" srcset="${link}${feature}.webp">
<source type="image/png" srcset="${link}${feature}.png">
<img src="${link}${feature}.jpg" alt="${alt}" width="100%">
</picture></p></ClientOnly>`
</picture></p>`
}
feature = feature.replace(UNDERLINE_RE, '_')
const { past, future } = resolveVersions(versions)
const meta = nanoid()
return `<CanIUseViewer${stringifyAttrs({ feature, meta, past, future })} />`
return `<CanIUseViewer${stringifyAttrs({ feature, meta, past, future, baseline: mode === 'baseline' })} />`
}
function resolveVersions(versions: string): { past: number, future: number } {

View File

@ -1,4 +1,8 @@
export type CanIUseMode = 'embed' | 'image'
export type CanIUseMode
= | 'embed'
| 'baseline'
/** @deprecated */
| 'image'
export interface CanIUseTokenMeta {
feature: string