vuepress-plugin-md-power 1.0.0-rc.48

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +201 -0
  3. package/lib/client/components/Bilibili.vue +45 -0
  4. package/lib/client/components/PDFViewer.vue +39 -0
  5. package/lib/client/components/Replit.vue +54 -0
  6. package/lib/client/components/Youtube.vue +41 -0
  7. package/lib/client/composables/pdf.d.ts +3 -0
  8. package/lib/client/composables/pdf.js +75 -0
  9. package/lib/client/composables/setupCanIUse.d.ts +1 -0
  10. package/lib/client/composables/setupCanIUse.js +18 -0
  11. package/lib/client/composables/size.d.ts +10 -0
  12. package/lib/client/composables/size.js +33 -0
  13. package/lib/client/config.d.ts +4 -0
  14. package/lib/client/config.js +27 -0
  15. package/lib/client/index.d.ts +1 -0
  16. package/lib/client/index.js +1 -0
  17. package/lib/client/options.d.ts +2 -0
  18. package/lib/client/options.js +1 -0
  19. package/lib/client/shim.d.ts +6 -0
  20. package/lib/client/utils/is.d.ts +3 -0
  21. package/lib/client/utils/is.js +13 -0
  22. package/lib/client/utils/link.d.ts +1 -0
  23. package/lib/client/utils/link.js +5 -0
  24. package/lib/node/features/caniuse.d.ts +25 -0
  25. package/lib/node/features/caniuse.js +129 -0
  26. package/lib/node/features/codepen.d.ts +7 -0
  27. package/lib/node/features/codepen.js +72 -0
  28. package/lib/node/features/icons/index.d.ts +2 -0
  29. package/lib/node/features/icons/index.js +2 -0
  30. package/lib/node/features/icons/plugin.d.ts +10 -0
  31. package/lib/node/features/icons/plugin.js +60 -0
  32. package/lib/node/features/icons/writer.d.ts +11 -0
  33. package/lib/node/features/icons/writer.js +100 -0
  34. package/lib/node/features/pdf.d.ts +2 -0
  35. package/lib/node/features/pdf.js +68 -0
  36. package/lib/node/features/replit.d.ts +7 -0
  37. package/lib/node/features/replit.js +59 -0
  38. package/lib/node/features/video/bilibili.d.ts +2 -0
  39. package/lib/node/features/video/bilibili.js +83 -0
  40. package/lib/node/features/video/youtube.d.ts +2 -0
  41. package/lib/node/features/video/youtube.js +74 -0
  42. package/lib/node/index.d.ts +2 -0
  43. package/lib/node/index.js +2 -0
  44. package/lib/node/markdown-it-container.d.ts +6 -0
  45. package/lib/node/plugin.d.ts +3 -0
  46. package/lib/node/plugin.js +55 -0
  47. package/lib/node/utils/package.d.ts +4 -0
  48. package/lib/node/utils/package.js +4 -0
  49. package/lib/node/utils/parseRect.d.ts +1 -0
  50. package/lib/node/utils/parseRect.js +5 -0
  51. package/lib/node/utils/resolveAttrs.d.ts +4 -0
  52. package/lib/node/utils/resolveAttrs.js +29 -0
  53. package/lib/node/utils/timeToSeconds.d.ts +1 -0
  54. package/lib/node/utils/timeToSeconds.js +8 -0
  55. package/lib/shared/caniuse.d.ts +18 -0
  56. package/lib/shared/caniuse.js +1 -0
  57. package/lib/shared/codepen.d.ts +10 -0
  58. package/lib/shared/codepen.js +1 -0
  59. package/lib/shared/icons.d.ts +17 -0
  60. package/lib/shared/icons.js +1 -0
  61. package/lib/shared/index.d.ts +6 -0
  62. package/lib/shared/index.js +6 -0
  63. package/lib/shared/pdf.d.ts +15 -0
  64. package/lib/shared/pdf.js +1 -0
  65. package/lib/shared/plugin.d.ts +12 -0
  66. package/lib/shared/plugin.js +1 -0
  67. package/lib/shared/replit.d.ts +6 -0
  68. package/lib/shared/replit.js +1 -0
  69. package/lib/shared/size.d.ts +5 -0
  70. package/lib/shared/size.js +1 -0
  71. package/lib/shared/video.d.ts +22 -0
  72. package/lib/shared/video.js +1 -0
  73. package/package.json +69 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (C) 2021 - PRESENT by pengzhanbo
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,201 @@
1
+ # vuepress-plugin-md-power
2
+
3
+ 为 vuepress 提供 丰富的 markdown 语法支持。
4
+
5
+ ## 功能
6
+
7
+ - caniuse 支持,提供前端各种特性在各个浏览器版本中的支持情况查看器
8
+ - 嵌入 PDF 支持
9
+ - 嵌入 视频支持,当前支持嵌入 bilibili 和 youtube 的视频
10
+ - 内联 iconify 图标支持
11
+
12
+ ## 安装
13
+
14
+ ```sh
15
+ pnpm add vuepress-plugin-md-power
16
+ ```
17
+
18
+ ## 使用
19
+
20
+ ```ts
21
+ import { defineUserConfig } from 'vuepress'
22
+ import { md } from 'vuepress-plugin-md-power'
23
+
24
+ export default defineUserConfig({
25
+ plugins: [
26
+ markdownPowerPlugin({
27
+ caniuse: true,
28
+ pdf: true,
29
+ bilibili: true,
30
+ youtube: true,
31
+ icons: true,
32
+ })
33
+ ]
34
+ })
35
+ ```
36
+
37
+ ### caniuse
38
+
39
+ 插件默认不启用该功能,你需要手动设置 `caniuse` 为 `true`
40
+
41
+ #### 语法
42
+
43
+ ```md
44
+ @[caniuse](feature)
45
+ @[caniuse image](feature)
46
+ @[caniuse embed{versions}](feature)
47
+ ```
48
+
49
+ 你可以从 [caniuse](https://caniuse.bitsofco.de/) 获取 feature 的值。
50
+
51
+ 默认情况下,插件通过 `iframe` 嵌入 `caniuse` 的支持情况查看器。
52
+ 你也可以使用 `@[caniuse image](feature)` 直接嵌入图片。
53
+
54
+ caniuse 默认查看最近的5个浏览器版本。你可以通过 `{versions}` 手动设置查看的浏览器版本。
55
+ 格式为 `{number,number,...}`。取值范围为 `-5 ~ 3` 。
56
+
57
+ - 小于0 表示低于当前浏览器版本的支持情况
58
+ - 0 表示当前浏览器版本的支持情况
59
+ - 大于0 表示高于当前浏览器版本的支持情况
60
+
61
+ 如 `{-2,-1,1,2}` 表示查看低于当前 2 个版本 到 高于当前 2 个版本的支持情况。
62
+
63
+ ### pdf
64
+
65
+ 插件默认不启用该功能,你需要手动设置 `pdf` 为 `true`
66
+
67
+ #### 语法
68
+
69
+ ```md
70
+ @[pdf](url)
71
+ @[pdf 1](url)
72
+ @[pdf 1 no-toolbar width="100%" height="600px" zoom="1" ratio="16:9"](url)
73
+ ```
74
+
75
+ `url` 只支持绝对路径以及完整的资源链接地址,请勿传入相对路径。
76
+
77
+ 你可以在 `pdf` 后紧跟空格,设置一个数字表示默认显示的 pdf 页码
78
+
79
+ - `no-toolbar` 表示不显示工具栏
80
+ - `width` 设置宽度
81
+ - `height` 设置高度
82
+ - `zoom` 设置缩放
83
+ - `ratio` 设置宽高比, 仅当 `width` 有值, `height` 未设置时有效
84
+
85
+ ### icons
86
+
87
+ 插件默认不启用该功能,你需要手动设置 `icons` 为 `true`。
88
+
89
+ 你还需要手动安装 `@iconify/json` 依赖。
90
+
91
+ ```sh
92
+ pnpm add @iconify/json
93
+ ```
94
+
95
+ #### 语法
96
+
97
+ ```md
98
+ :[collect:icon]:
99
+ :[collect:icon size]:
100
+ :[collect:icon /color]:
101
+ :[collect:icon size/color]:
102
+ ```
103
+
104
+ 你可以从 [icon-sets.iconify](https://icon-sets.iconify.design/) 获取 图标集。
105
+
106
+ 显示 `logos` 图标集合下的 `vue` 图标
107
+
108
+ ```md
109
+ :[logos:vue]:
110
+ ```
111
+
112
+ 图标默认大小为 `1em` ,你可以通过 `size` 设置图标大小
113
+
114
+ ```md
115
+ :[logos:vue 1.2em]:
116
+ ```
117
+
118
+ 图标默认颜色为 `currentColor` 你可以通过 `/color` 设置图标颜色
119
+
120
+ ```md
121
+ :[logos:vue /blue]:
122
+ ```
123
+
124
+ 也可以通过 `size/color` 设置图标大小和颜色
125
+
126
+ ```md
127
+ :[logos:vue 1.2em/blue]:
128
+ ```
129
+
130
+ ### bilibili
131
+
132
+ 插件默认不启用该功能,你需要手动设置 `bilibili` 为 `true`
133
+
134
+ #### 语法
135
+
136
+ ```md
137
+ @[bilibili](bvid)
138
+ @[bilibili autoplay time="0"](bvid)
139
+ @[bilibili p1 autoplay time="0" ratio="16:9"](aid cid)
140
+ ```
141
+
142
+ - 设置 `autoplay` 以自动播放视频。
143
+ - 设置 `time` 以指定开始播放的时间点,单位为秒。还可以传入 `mm:ss` 或者 `hh:mm:ss`。
144
+ - 如果为 分p(非合集),还可以设置 `p\d` (第\d 个分p),此时可以只传入 `aid` 和 `cid`。
145
+ - 设置 `ratio` 以指定视频的宽高比。
146
+
147
+ ### youtube
148
+
149
+ 插件默认不启用该功能,你需要手动设置 `youtube` 为 `true`
150
+
151
+ #### 语法
152
+
153
+ ```md
154
+ @[youtube](id)
155
+ @[youtube autoplay loop ratio="16:9" star="0" end="0"](id)
156
+ ```
157
+
158
+ - `id` 为 YouTube 视频 ID
159
+ - `autoplay` 为是否自动播放
160
+ - `loop` 为是否循环播放
161
+ - `ratio` 为视频的宽高比
162
+ - `star` 为开始时间,单位为秒,还可以传入 `mm:ss` 或者 `hh:mm:ss`。
163
+ - `end` 为结束时间,单位为秒,还可以传入 `mm:ss` 或者 `hh:mm:ss`。
164
+
165
+ ### CodePen
166
+
167
+ 插件默认不启用该功能,你需要手动设置 `codepen` 为 `true`
168
+
169
+ #### 语法
170
+
171
+ ```md
172
+ @[codepen](user/slash)
173
+ @[codepen preview editable title="" height="400px" tab="css,result" theme="dark"](user/slash)
174
+ ```
175
+
176
+ - `user` 为 CodePen 用户名
177
+ - `slash` 为 CodePen slash
178
+ - `preview` 为是否为预览模式
179
+ - `editable` 为是否为可编辑模式
180
+ - `title` 为标题
181
+ - `height` 为高度
182
+ - `tab` 为选项卡,默认为 `result`, 多个以逗号分隔,如 `css,result`
183
+ - `theme` 为主题, 可选值包括 `dark` 和 `light`
184
+
185
+ ### Replit
186
+
187
+ 插件默认不启用该功能,你需要手动设置 `replit` 为 `true`
188
+
189
+ #### 语法
190
+
191
+ ```md
192
+ @[replit](user/repl-name)
193
+ @[replit title="" height="450px" theme="dark"](user/repl-name#filepath)
194
+ ```
195
+
196
+ - `user` 为 Replit 用户名
197
+ - `repl-name` 为 Replit Repl 名
198
+ - `filepath` 为文件路径
199
+ - `title` 为标题
200
+ - `height` 为高度
201
+ - `theme` 为主题, 可选值包括 `dark` 和 `light`
@@ -0,0 +1,45 @@
1
+ <script setup lang="ts">
2
+ import { toRefs } from 'vue'
3
+ import { useSize } from '../composables/size.js'
4
+
5
+ const props = defineProps<{
6
+ src: string
7
+ title: string
8
+ width?: string
9
+ height?: string
10
+ ratio?: string
11
+ }>()
12
+
13
+ const IFRAME_ALLOW = 'accelerometer; autoplay; clipboard-write; encrypted-media; fullscreen; gyroscope; picture-in-picture'
14
+
15
+ const options = toRefs(props)
16
+
17
+ const { el, width, height, resize } = useSize(options)
18
+
19
+ function onLoad() {
20
+ resize()
21
+ }
22
+ </script>
23
+
24
+ <template>
25
+ <ClientOnly>
26
+ <iframe
27
+ ref="el"
28
+ class="video_bilibili_iframe"
29
+ :src="src"
30
+ :title="title || 'Bilibili'"
31
+ :style="{ width, height }"
32
+ :allow="IFRAME_ALLOW"
33
+ @load="onLoad"
34
+ />
35
+ </ClientOnly>
36
+ </template>
37
+
38
+ <style>
39
+ .video_bilibili_iframe {
40
+ width: 100%;
41
+ margin: 16px auto;
42
+ border: none;
43
+ border-radius: 5px;
44
+ }
45
+ </style>
@@ -0,0 +1,39 @@
1
+ <script setup lang="ts">
2
+ import { onMounted, toRefs } from 'vue'
3
+ import type { PDFTokenMeta } from '../../shared/pdf.js'
4
+ import { useSize } from '../composables/size.js'
5
+ import { usePDF } from '../composables/pdf.js'
6
+
7
+ const props = defineProps<PDFTokenMeta>()
8
+
9
+ const options = toRefs(props)
10
+ const { el, width, height, resize } = useSize(options)
11
+
12
+ onMounted(() => {
13
+ if (!el.value)
14
+ return
15
+ usePDF(el.value, props.src!, {
16
+ page: props.page,
17
+ zoom: props.zoom,
18
+ noToolbar: props.noToolbar,
19
+ })
20
+ resize()
21
+ })
22
+ </script>
23
+
24
+ <template>
25
+ <div ref="el" class="pdf-viewer-wrapper" :style="{ width, height }" />
26
+ </template>
27
+
28
+ <style>
29
+ .pdf-viewer-wrapper {
30
+ position: relative;
31
+ overflow: hidden;
32
+ border-radius: 4px;
33
+ }
34
+
35
+ .pdf-viewer {
36
+ width: 100%;
37
+ height: 100%;
38
+ }
39
+ </style>
@@ -0,0 +1,54 @@
1
+ <script setup lang="ts">
2
+ import { computed, getCurrentInstance, ref } from 'vue'
3
+ import type { ReplitTokenMeta } from '../../shared/replit.js'
4
+
5
+ const props = defineProps<ReplitTokenMeta>()
6
+
7
+ const current = getCurrentInstance()
8
+ // magic height
9
+ const height = ref('47px')
10
+
11
+ const REPLIT_LINK = 'https://replit.com/'
12
+
13
+ const isDark = computed(() => current?.appContext.config.globalProperties.$isDark.value)
14
+
15
+ const link = computed(() => {
16
+ const url = new URL(`/${props.source}`, REPLIT_LINK)
17
+ url.searchParams.set('embed', 'true')
18
+
19
+ const theme = props.theme || (isDark.value ? 'dark' : 'light')
20
+ url.searchParams.set('theme', theme)
21
+
22
+ return url.toString()
23
+ })
24
+
25
+ function onload() {
26
+ height.value = props.height || '450px'
27
+ }
28
+ </script>
29
+
30
+ <template>
31
+ <ClientOnly>
32
+ <iframe
33
+ class="replit-iframe-wrapper"
34
+ :src="link"
35
+ :title="title || 'Replit'"
36
+ :style="{ width, height }"
37
+ allowtransparency="true"
38
+ allowfullscree="true"
39
+ @load="onload"
40
+ />
41
+ </ClientOnly>
42
+ </template>
43
+
44
+ <style>
45
+ .replit-iframe-wrapper {
46
+ width: 100%;
47
+ margin: 16px auto;
48
+ border: none;
49
+ border-top: 1px solid var(--vp-c-divider);
50
+ border-bottom-right-radius: 8px;
51
+ border-bottom-left-radius: 8px;
52
+ transition: border 0.25s;
53
+ }
54
+ </style>
@@ -0,0 +1,41 @@
1
+ <script setup lang="ts">
2
+ import { toRefs } from 'vue'
3
+ import { useSize } from '../composables/size.js'
4
+
5
+ const props = defineProps<{
6
+ src: string
7
+ title: string
8
+ width?: string
9
+ height?: string
10
+ ratio?: string
11
+ }>()
12
+
13
+ const IFRAME_ALLOW = 'accelerometer; autoplay; clipboard-write; encrypted-media; fullscreen; gyroscope; picture-in-picture'
14
+
15
+ const options = toRefs(props)
16
+
17
+ const { el, width, height, resize } = useSize(options)
18
+ </script>
19
+
20
+ <template>
21
+ <ClientOnly>
22
+ <iframe
23
+ ref="el"
24
+ class="video_youtube_iframe"
25
+ :src="src"
26
+ :title="title || 'Youtube'"
27
+ :style="{ width, height }"
28
+ :allow="IFRAME_ALLOW"
29
+ @load="resize"
30
+ />
31
+ </ClientOnly>
32
+ </template>
33
+
34
+ <style>
35
+ .video_youtube_iframe {
36
+ width: 100%;
37
+ margin: 16px auto;
38
+ border: none;
39
+ border-radius: 5px;
40
+ }
41
+ </style>
@@ -0,0 +1,3 @@
1
+ import type { PDFEmbedType, PDFTokenMeta } from '../../shared/pdf.js';
2
+ export declare function renderPDF(el: HTMLElement, url: string, embedType: PDFEmbedType, options: PDFTokenMeta): void;
3
+ export declare function usePDF(el: HTMLElement, url: string, options: PDFTokenMeta): void;
@@ -0,0 +1,75 @@
1
+ import { ensureEndingSlash } from 'vuepress/shared';
2
+ import { withBase } from 'vuepress/client';
3
+ import { normalizeLink } from '../utils/link.js';
4
+ import { pluginOptions } from '../options.js';
5
+ import { checkIsMobile, checkIsSafari, checkIsiPad } from '../utils/is.js';
6
+ function queryStringify(options) {
7
+ const { page, noToolbar, zoom } = options;
8
+ const params = [
9
+ `page=${page}`,
10
+ `toolbar=${noToolbar ? 0 : 1}`,
11
+ `zoom=${zoom}`,
12
+ ];
13
+ let queryString = params.join('&');
14
+ if (queryString)
15
+ queryString = `#${queryString}`;
16
+ return queryString;
17
+ }
18
+ export function renderPDF(el, url, embedType, options) {
19
+ if (!pluginOptions.pdf)
20
+ return;
21
+ url = normalizeLink(url);
22
+ const pdfOptions = pluginOptions.pdf === true ? {} : pluginOptions.pdf;
23
+ const pdfjsUrl = pdfOptions.pdfjsUrl
24
+ ? `${ensureEndingSlash(withBase(pdfOptions.pdfjsUrl))}web/viewer.html`
25
+ : '';
26
+ const queryString = queryStringify(options);
27
+ const source = embedType === 'pdfjs'
28
+ ? `${pdfjsUrl}?file=${encodeURIComponent(url)}${queryString}`
29
+ : `${url}${queryString}`;
30
+ const tagName = embedType === 'pdfjs' || embedType === 'iframe'
31
+ ? 'iframe'
32
+ : 'embed';
33
+ el.innerHTML = '';
34
+ const pdf = document.createElement(tagName);
35
+ pdf.className = 'pdf-viewer';
36
+ pdf.type = 'application/pdf';
37
+ pdf.title = options.title || 'PDF Viewer';
38
+ pdf.src = source;
39
+ if (pdf instanceof HTMLIFrameElement)
40
+ pdf.allow = 'fullscreen';
41
+ el.appendChild(pdf);
42
+ }
43
+ export function usePDF(el, url, options) {
44
+ if (typeof window === 'undefined' || !window?.navigator?.userAgent)
45
+ return;
46
+ const { navigator } = window;
47
+ const { userAgent } = navigator;
48
+ const isModernBrowser = typeof window.Promise === 'function';
49
+ // Quick test for mobile devices.
50
+ const isMobileDevice = checkIsiPad(userAgent) || checkIsMobile(userAgent);
51
+ // Safari desktop requires special handling
52
+ const isSafariDesktop = !isMobileDevice && checkIsSafari(userAgent);
53
+ const isFirefoxWithPDFJS = !isMobileDevice
54
+ && /firefox/iu.test(userAgent)
55
+ && userAgent.split('rv:').length > 1
56
+ ? Number.parseInt(userAgent.split('rv:')[1].split('.')[0], 10) > 18
57
+ : false;
58
+ // Determines whether PDF support is available
59
+ const supportsPDFs
60
+ // As of Sept 2020 no mobile browsers properly support PDF embeds
61
+ = !isMobileDevice
62
+ // We're moving into the age of MIME-less browsers. They mostly all support PDF rendering without plugins.
63
+ && (isModernBrowser
64
+ // Modern versions of Firefox come bundled with PDFJS
65
+ || isFirefoxWithPDFJS);
66
+ if (!url)
67
+ return;
68
+ if (supportsPDFs || !isMobileDevice) {
69
+ const embedType = isSafariDesktop ? 'iframe' : 'embed';
70
+ return renderPDF(el, url, embedType, options);
71
+ }
72
+ if (typeof pluginOptions.pdf === 'object' && pluginOptions.pdf.pdfjsUrl)
73
+ return renderPDF(el, url, 'pdfjs', options);
74
+ el.innerHTML = `<p>This browser does not support embedding PDFs. Please download the PDF to view it: <a href='${url}' target='_blank'>Download PDF</a></p>`;
75
+ }
@@ -0,0 +1 @@
1
+ export declare function setupCanIUse(): void;
@@ -0,0 +1,18 @@
1
+ let isBind = false;
2
+ export function setupCanIUse() {
3
+ if (isBind)
4
+ return;
5
+ isBind = true;
6
+ window.addEventListener('message', (message) => {
7
+ const data = message.data;
8
+ if (typeof data === 'string' && data.includes('ciu_embed')) {
9
+ const [, feature, height] = data.split(':');
10
+ const el = document.querySelector(`.ciu_embed[data-feature="${feature}"]:not([data-skip])`);
11
+ if (el) {
12
+ const h = Number.parseInt(height) + 30;
13
+ el.childNodes[0].height = `${h}px`;
14
+ el.setAttribute('data-skip', 'true');
15
+ }
16
+ }
17
+ });
18
+ }
@@ -0,0 +1,10 @@
1
+ import type { MaybeRef } from '@vueuse/core';
2
+ import type { Ref, ShallowRef, ToRefs } from 'vue';
3
+ import type { SizeOptions } from '../../shared/size.js';
4
+ export interface SizeInfo<T extends HTMLElement> {
5
+ el: ShallowRef<T | undefined>;
6
+ width: Ref<string>;
7
+ height: Ref<string>;
8
+ resize: () => void;
9
+ }
10
+ export declare function useSize<T extends HTMLElement>(options: ToRefs<SizeOptions>, extraHeight?: MaybeRef<number>): SizeInfo<T>;
@@ -0,0 +1,33 @@
1
+ import { useEventListener } from '@vueuse/core';
2
+ import { computed, isRef, onMounted, ref, shallowRef, toValue, watch } from 'vue';
3
+ export function useSize(options, extraHeight = 0) {
4
+ const el = shallowRef();
5
+ const width = computed(() => toValue(options.width) || '100%');
6
+ const height = ref('auto');
7
+ const getRadio = (ratio) => {
8
+ if (typeof ratio === 'string') {
9
+ const [width, height] = ratio.split(':');
10
+ const parsedRadio = Number(width) / Number(height);
11
+ if (!Number.isNaN(parsedRadio))
12
+ return parsedRadio;
13
+ }
14
+ return typeof ratio === 'number' ? ratio : 16 / 9;
15
+ };
16
+ const getHeight = (width) => {
17
+ const height = toValue(options.height);
18
+ const ratio = getRadio(toValue(options.ratio));
19
+ return height || `${Number(width) / ratio + toValue(extraHeight)}px`;
20
+ };
21
+ const resize = () => {
22
+ if (el.value)
23
+ height.value = getHeight(el.value.offsetWidth);
24
+ };
25
+ onMounted(() => {
26
+ resize();
27
+ if (isRef(extraHeight))
28
+ watch(extraHeight, resize);
29
+ useEventListener('orientationchange', resize);
30
+ useEventListener('resize', resize);
31
+ });
32
+ return { el, width, height, resize };
33
+ }
@@ -0,0 +1,4 @@
1
+ import type { ClientConfig } from 'vuepress/client';
2
+ import '@internal/md-power/icons.css';
3
+ declare const _default: ClientConfig;
4
+ export default _default;
@@ -0,0 +1,27 @@
1
+ import { defineClientConfig } from 'vuepress/client';
2
+ import { pluginOptions } from './options.js';
3
+ import { setupCanIUse } from './composables/setupCanIUse.js';
4
+ import PDFViewer from './components/PDFViewer.vue';
5
+ import Bilibili from './components/Bilibili.vue';
6
+ import Youtube from './components/Youtube.vue';
7
+ import Replit from './components/Replit.vue';
8
+ import '@internal/md-power/icons.css';
9
+ export default defineClientConfig({
10
+ enhance({ router, app }) {
11
+ if (pluginOptions.pdf)
12
+ app.component('PDFViewer', PDFViewer);
13
+ if (pluginOptions.bilibili)
14
+ app.component('VideoBilibili', Bilibili);
15
+ if (pluginOptions.youtube)
16
+ app.component('VideoYoutube', Youtube);
17
+ if (pluginOptions.replit)
18
+ app.component('ReplitViewer', Replit);
19
+ if (__VUEPRESS_SSR__)
20
+ return;
21
+ if (pluginOptions.caniuse) {
22
+ router.afterEach(() => {
23
+ setupCanIUse();
24
+ });
25
+ }
26
+ },
27
+ });
@@ -0,0 +1 @@
1
+ export * from '../shared/index.js';
@@ -0,0 +1 @@
1
+ export * from '../shared/index.js';
@@ -0,0 +1,2 @@
1
+ import type { MarkdownPowerPluginOptions } from '../shared/index.js';
2
+ export declare const pluginOptions: MarkdownPowerPluginOptions;
@@ -0,0 +1 @@
1
+ export const pluginOptions = __MD_POWER_INJECT_OPTIONS__;
@@ -0,0 +1,6 @@
1
+ declare module '*.vue' {
2
+ import type { ComponentOptions } from 'vue'
3
+
4
+ const comp: ComponentOptions
5
+ export default comp
6
+ }
@@ -0,0 +1,3 @@
1
+ export declare function checkIsMobile(ua: string): boolean;
2
+ export declare function checkIsSafari(ua: string): boolean;
3
+ export declare function checkIsiPad(ua: string): boolean;
@@ -0,0 +1,13 @@
1
+ export function checkIsMobile(ua) {
2
+ return /\b(?:Android|iPhone)/i.test(ua);
3
+ }
4
+ export function checkIsSafari(ua) {
5
+ return /version\/([\w.]+) .*(mobile ?safari|safari)/i.test(ua);
6
+ }
7
+ export function checkIsiPad(ua) {
8
+ return [
9
+ /\((ipad);[-\w),; ]+apple/i,
10
+ /applecoremedia\/[\w.]+ \((ipad)/i,
11
+ /\b(ipad)\d\d?,\d\d?[;\]].+ios/i,
12
+ ].some(item => item.test(ua));
13
+ }
@@ -0,0 +1 @@
1
+ export declare function normalizeLink(url: string): string;
@@ -0,0 +1,5 @@
1
+ import { isLinkHttp } from 'vuepress/shared';
2
+ import { withBase } from 'vuepress/client';
3
+ export function normalizeLink(url) {
4
+ return isLinkHttp(url) ? url : withBase(url);
5
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * @[caniuse embed{1,2,3,4}](feature_name)
3
+ * @[caniuse image](feature_name)
4
+ */
5
+ import type { PluginWithOptions } from 'markdown-it';
6
+ import type { Markdown } from 'vuepress/markdown';
7
+ import type { CanIUseOptions } from '../../shared/index.js';
8
+ /**
9
+ * @example
10
+ * ```md
11
+ * @[caniuse](feature_name)
12
+ * ```
13
+ */
14
+ export declare const caniusePlugin: PluginWithOptions<CanIUseOptions>;
15
+ /**
16
+ * @deprecated use caniuse plugin
17
+ *
18
+ * 兼容旧语法
19
+ * @example
20
+ * ```md
21
+ * :::caniuse <feature_name>
22
+ * :::
23
+ * ```
24
+ */
25
+ export declare function legacyCaniuse(md: Markdown, { mode }?: CanIUseOptions): void;