vuepress-plugin-md-power 1.0.0-rc.145 → 1.0.0-rc.147

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.
@@ -9,6 +9,7 @@ const props = defineProps<{
9
9
  diff?: 'add' | 'remove'
10
10
  expanded?: boolean
11
11
  focus?: boolean
12
+ filepath?: string
12
13
  }>()
13
14
 
14
15
  const activeFileTreeNode = inject<Ref<string>>('active-file-tree-node', ref(''))
@@ -23,7 +24,7 @@ function nodeClick() {
23
24
  if (props.filename === '…' || props.filename === '...')
24
25
  return
25
26
 
26
- onNodeClick(props.filename, props.type)
27
+ onNodeClick(props.filepath || props.filename, props.type)
27
28
  }
28
29
 
29
30
  function toggle(ev: MouseEvent) {
@@ -47,7 +48,7 @@ function toggle(ev: MouseEvent) {
47
48
  [type]: true,
48
49
  focus,
49
50
  expanded: type === 'folder' ? active : false,
50
- active: type === 'file' ? activeFileTreeNode === filename : false,
51
+ active: type === 'file' ? activeFileTreeNode === filepath : false,
51
52
  diff,
52
53
  add: diff === 'add',
53
54
  remove: diff === 'remove',
@@ -0,0 +1,175 @@
1
+ <script setup lang="ts">
2
+ import { onMounted, provide, ref, useTemplateRef, watch } from 'vue'
3
+
4
+ const props = withDefaults(defineProps<{
5
+ title?: string
6
+ height?: string
7
+ entryFile?: string
8
+ }>(), { height: '320px' })
9
+
10
+ const activeNode = ref(props.entryFile || '')
11
+ const isEmpty = ref(true)
12
+ const codePanel = useTemplateRef<HTMLDivElement>('codePanel')
13
+
14
+ provide('active-file-tree-node', activeNode)
15
+ provide('on-file-tree-node-click', (filepath: string, type: 'file' | 'folder') => {
16
+ if (type === 'file') {
17
+ activeNode.value = filepath
18
+ }
19
+ })
20
+
21
+ onMounted(() => {
22
+ watch(
23
+ () => activeNode.value,
24
+ () => {
25
+ if (codePanel.value) {
26
+ const items = Array.from(codePanel.value.querySelectorAll('.code-block-title'))
27
+ let hasActive = false
28
+ items.forEach((item) => {
29
+ if (item.getAttribute('data-title') === activeNode.value) {
30
+ item.classList.add('active')
31
+ hasActive = true
32
+ }
33
+ else {
34
+ item.classList.remove('active')
35
+ }
36
+ })
37
+ isEmpty.value = !hasActive
38
+ }
39
+ },
40
+ { immediate: true },
41
+ )
42
+ })
43
+ </script>
44
+
45
+ <template>
46
+ <div class="vp-code-tree">
47
+ <div class="code-tree-panel" :style="{ 'max-height': props.height }">
48
+ <div v-if="title" class="code-tree-title" :title="title">
49
+ <span>{{ title }}</span>
50
+ </div>
51
+ <div class="vp-file-tree">
52
+ <slot name="file-tree" />
53
+ </div>
54
+ </div>
55
+ <div ref="codePanel" class="code-panel" :style="{ height: props.height }">
56
+ <slot />
57
+ <div v-if="isEmpty" class="code-tree-empty">
58
+ <span class="vpi-code-tree-empty" />
59
+ </div>
60
+ </div>
61
+ </div>
62
+ </template>
63
+
64
+ <style>
65
+ .vp-code-tree {
66
+ width: 100%;
67
+ margin: 16px 0;
68
+ overflow: hidden;
69
+ border: solid 1px var(--vp-c-divider);
70
+ border-radius: 6px;
71
+ }
72
+
73
+ @media (min-width: 768px) {
74
+ .vp-code-tree {
75
+ display: grid;
76
+ grid-template-columns: repeat(3, minmax(0, 1fr));
77
+ }
78
+ }
79
+
80
+ .vp-code-tree .code-tree-panel {
81
+ display: flex;
82
+ flex-direction: column;
83
+ border-bottom: solid 1px var(--vp-c-divider);
84
+ }
85
+
86
+ @media (min-width: 768px) {
87
+ .vp-code-tree .code-tree-panel {
88
+ border-right: solid 1px var(--vp-c-divider);
89
+ border-bottom: none;
90
+ }
91
+ }
92
+
93
+ .vp-code-tree .code-tree-panel .code-tree-title {
94
+ height: 40px;
95
+ padding: 0 16px;
96
+ overflow: hidden;
97
+ font-weight: 500;
98
+ line-height: 40px;
99
+ text-overflow: ellipsis;
100
+ white-space: nowrap;
101
+ border-bottom: solid 1px var(--vp-c-divider);
102
+ }
103
+
104
+ .vp-code-tree .code-tree-panel .vp-file-tree {
105
+ flex: 1 2;
106
+ margin: 0;
107
+ overflow: auto;
108
+ background-color: transparent;
109
+ border: none;
110
+ border-radius: 0;
111
+ }
112
+
113
+ .vp-code-tree .code-tree-panel .vp-file-tree .vp-file-tree-info.file {
114
+ cursor: pointer;
115
+ }
116
+
117
+ .vp-code-tree .code-panel {
118
+ grid-column: span 2 / span 2;
119
+ }
120
+
121
+ .vp-code-tree .code-panel [class*="language-"] {
122
+ flex: 1 2;
123
+ margin: 16px 0 0;
124
+ overflow: auto;
125
+ border-bottom-right-radius: 0;
126
+ border-bottom-left-radius: 0;
127
+ }
128
+
129
+ @media (min-width: 768px) {
130
+ .vp-code-tree .code-tree-panel .vp-file-tree,
131
+ .vp-code-tree .code-panel [class*="language-"] {
132
+ overscroll-behavior: contain;
133
+ }
134
+ }
135
+
136
+ .vp-code-tree .code-panel .code-block-title {
137
+ display: none;
138
+ height: 100%;
139
+ }
140
+
141
+ .vp-code-tree .code-panel .code-block-title.active {
142
+ display: flex;
143
+ flex-direction: column;
144
+ }
145
+
146
+ .vp-code-tree .code-panel .code-block-title .code-block-title-bar {
147
+ margin-top: 0;
148
+ border-radius: 0;
149
+ }
150
+
151
+ .vp-code-tree .code-panel div[class*="language-"].has-collapsed-lines.collapsed {
152
+ height: auto;
153
+ overflow: auto;
154
+ }
155
+
156
+ .vp-code-tree .code-panel div[class*="language-"].has-collapsed-lines .collapsed-lines {
157
+ display: none;
158
+ }
159
+
160
+ .vp-code-tree .code-panel .code-tree-empty {
161
+ display: flex;
162
+ align-items: center;
163
+ justify-content: center;
164
+ width: 100%;
165
+ height: 100%;
166
+ }
167
+
168
+ .vp-code-tree .code-panel .code-tree-empty .vpi-code-tree-empty {
169
+ --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='256' height='256' viewBox='0 0 256 256'%3E%3Cpath fill='%23000' d='m198.24 62.63l15.68-17.25a8 8 0 0 0-11.84-10.76L186.4 51.86A95.95 95.95 0 0 0 57.76 193.37l-15.68 17.25a8 8 0 1 0 11.84 10.76l15.68-17.24A95.95 95.95 0 0 0 198.24 62.63M48 128a80 80 0 0 1 127.6-64.25l-107 117.73A79.63 79.63 0 0 1 48 128m80 80a79.55 79.55 0 0 1-47.6-15.75l107-117.73A79.95 79.95 0 0 1 128 208'/%3E%3C/svg%3E");
170
+
171
+ width: 128px;
172
+ height: 128px;
173
+ color: var(--vp-c-default-soft);
174
+ }
175
+ </style>
@@ -1,40 +1,40 @@
1
- import * as vue from 'vue';
2
- import { MaybeRef } from 'vue';
1
+ import { MaybeRef, Ref } from "vue";
3
2
 
3
+ //#region src/client/composables/audio.d.ts
4
4
  interface BufferedRange {
5
- start: number;
6
- end: number;
5
+ start: number;
6
+ end: number;
7
7
  }
8
8
  interface AudioPlayerOptions {
9
- type?: MaybeRef<string>;
10
- autoplay?: boolean;
11
- mutex?: boolean;
12
- onload?: HTMLAudioElement['onload'];
13
- onerror?: HTMLAudioElement['onerror'];
14
- onpause?: HTMLAudioElement['onpause'];
15
- onplay?: HTMLAudioElement['onplay'];
16
- onplaying?: HTMLAudioElement['onplaying'];
17
- onseeked?: HTMLAudioElement['onseeked'];
18
- onvolume?: (volume: number) => void;
19
- onend?: HTMLAudioElement['onended'];
20
- onprogress?: (current: number, total: number) => void;
21
- oncanplay?: HTMLAudioElement['oncanplay'];
22
- oncanplaythrough?: HTMLAudioElement['oncanplaythrough'];
23
- ontimeupdate?: (currentTime: number) => void;
24
- onwaiting?: HTMLAudioElement['onwaiting'];
9
+ type?: MaybeRef<string>;
10
+ autoplay?: boolean;
11
+ mutex?: boolean;
12
+ onload?: HTMLAudioElement["onload"];
13
+ onerror?: HTMLAudioElement["onerror"];
14
+ onpause?: HTMLAudioElement["onpause"];
15
+ onplay?: HTMLAudioElement["onplay"];
16
+ onplaying?: HTMLAudioElement["onplaying"];
17
+ onseeked?: HTMLAudioElement["onseeked"];
18
+ onvolume?: (volume: number) => void;
19
+ onend?: HTMLAudioElement["onended"];
20
+ onprogress?: (current: number, total: number) => void;
21
+ oncanplay?: HTMLAudioElement["oncanplay"];
22
+ oncanplaythrough?: HTMLAudioElement["oncanplaythrough"];
23
+ ontimeupdate?: (currentTime: number) => void;
24
+ onwaiting?: HTMLAudioElement["onwaiting"];
25
25
  }
26
- declare function useAudioPlayer(source: MaybeRef<string>, options?: AudioPlayerOptions): {
27
- isSupported: vue.Ref<boolean, boolean>;
28
- paused: vue.Ref<boolean, boolean>;
29
- loaded: vue.Ref<boolean, boolean>;
30
- currentTime: vue.Ref<number, number>;
31
- duration: vue.Ref<number, number>;
32
- player: null;
33
- destroy: () => void;
34
- play: () => void;
35
- pause: () => void | undefined;
36
- seek(time: number): void;
37
- setVolume(volume: number): void;
38
- };
39
-
40
- export { type AudioPlayerOptions, type BufferedRange, useAudioPlayer };
26
+ interface UseAudioPlayerResult {
27
+ player: HTMLAudioElement | null;
28
+ isSupported: Ref<boolean>;
29
+ loaded: Ref<boolean>;
30
+ paused: Ref<boolean>;
31
+ currentTime: Ref<number>;
32
+ duration: Ref<number>;
33
+ play: () => void;
34
+ pause: () => void;
35
+ seek: (time: number) => void;
36
+ setVolume: (volume: number) => void;
37
+ destroy: () => void;
38
+ }
39
+ declare function useAudioPlayer(source: MaybeRef<string>, options?: AudioPlayerOptions): UseAudioPlayerResult; //#endregion
40
+ export { AudioPlayerOptions, BufferedRange, useAudioPlayer };
@@ -1,185 +1,173 @@
1
- // src/client/composables/audio.ts
2
1
  import { onMounted, onUnmounted, ref, toValue, watch } from "vue";
3
- var mimeTypes = {
4
- "audio/flac": ["flac", "fla"],
5
- "audio/mpeg": ["mp3", "mpga"],
6
- "audio/mp4": ["mp4", "m4a"],
7
- "audio/ogg": ["ogg", "oga"],
8
- "audio/aac": ["aac", "adts"],
9
- "audio/x-ms-wma": ["wma"],
10
- "audio/x-aiff": ["aiff", "aif", "aifc"],
11
- "audio/webm": ["webm"]
2
+
3
+ //#region src/client/composables/audio.ts
4
+ const mimeTypes = {
5
+ "audio/flac": ["flac", "fla"],
6
+ "audio/mpeg": ["mp3", "mpga"],
7
+ "audio/mp4": ["mp4", "m4a"],
8
+ "audio/ogg": ["ogg", "oga"],
9
+ "audio/aac": ["aac", "adts"],
10
+ "audio/x-ms-wma": ["wma"],
11
+ "audio/x-aiff": [
12
+ "aiff",
13
+ "aif",
14
+ "aifc"
15
+ ],
16
+ "audio/webm": ["webm"]
12
17
  };
13
- var playerList = [];
18
+ const playerList = [];
14
19
  function useAudioPlayer(source, options = {}) {
15
- let player = null;
16
- let unknownSupport = false;
17
- const isSupported = ref(false);
18
- const loaded = ref(false);
19
- const paused = ref(true);
20
- const currentTime = ref(0);
21
- const duration = ref(0);
22
- const volume = ref(1);
23
- function initialize() {
24
- player = document.createElement("audio");
25
- player.className = "audio-player";
26
- player.style.display = "none";
27
- player.preload = options.autoplay ? "auto" : "none";
28
- player.autoplay = options.autoplay ?? false;
29
- document.body.appendChild(player);
30
- playerList.push(player);
31
- player.onloadedmetadata = () => {
32
- duration.value = player.duration;
33
- currentTime.value = player.currentTime;
34
- volume.value = player.volume;
35
- loaded.value = true;
36
- };
37
- player.oncanplay = (...args) => {
38
- loaded.value = true;
39
- if (unknownSupport)
40
- isSupported.value = true;
41
- options.oncanplay?.bind(player)(...args);
42
- };
43
- player.onplay = (...args) => {
44
- paused.value = false;
45
- options.onplay?.bind(player)(...args);
46
- };
47
- player.onpause = (...args) => {
48
- paused.value = true;
49
- options.onpause?.bind(player)(...args);
50
- };
51
- player.ontimeupdate = () => {
52
- if (isValidDuration(player.duration)) {
53
- const lastBufferTime = getLastBufferedTime();
54
- if (lastBufferTime <= player.duration) {
55
- options.ontimeupdate?.bind(player)(lastBufferTime);
56
- currentTime.value = lastBufferTime;
57
- options.onprogress?.bind(player)(lastBufferTime, player.duration);
58
- }
59
- }
60
- };
61
- player.onvolumechange = () => {
62
- volume.value = player.volume;
63
- options.onvolume?.bind(player)(player.volume);
64
- };
65
- player.onended = (...args) => {
66
- paused.value = true;
67
- options.onend?.bind(player)(...args);
68
- };
69
- player.onplaying = options.onplaying;
70
- player.onload = options.onload;
71
- player.onerror = options.onerror;
72
- player.onseeked = options.onseeked;
73
- player.oncanplaythrough = options.oncanplaythrough;
74
- player.onwaiting = options.onwaiting;
75
- isSupported.value = isSupportType();
76
- player.src = toValue(source);
77
- player.load();
78
- }
79
- function isSupportType() {
80
- if (!player)
81
- return false;
82
- let type = toValue(options.type);
83
- if (!type) {
84
- const ext = toValue(source).split(".").pop() || "";
85
- type = Object.keys(mimeTypes).filter((type2) => mimeTypes[type2].includes(ext))[0];
86
- }
87
- if (!type) {
88
- unknownSupport = true;
89
- return false;
90
- }
91
- const isSupported2 = player.canPlayType(type) !== "";
92
- if (!isSupported2) {
93
- console.warn(`The specified type "${type}" is not supported by the browser.`);
94
- }
95
- return isSupported2;
96
- }
97
- function getBufferedRanges() {
98
- if (!player)
99
- return [];
100
- const ranges = [];
101
- const seekable = player.buffered || [];
102
- const offset = 0;
103
- for (let i = 0, length = seekable.length; i < length; i++) {
104
- let start = seekable.start(i);
105
- let end = seekable.end(i);
106
- if (!isValidDuration(start))
107
- start = 0;
108
- if (!isValidDuration(end)) {
109
- end = 0;
110
- continue;
111
- }
112
- ranges.push({
113
- start: start + offset,
114
- end: end + offset
115
- });
116
- }
117
- return ranges;
118
- }
119
- function getLastBufferedTime() {
120
- const bufferedRanges = getBufferedRanges();
121
- if (!bufferedRanges.length)
122
- return 0;
123
- const buff = bufferedRanges.find(
124
- (buff2) => buff2.start < player.currentTime && buff2.end > player.currentTime
125
- );
126
- if (buff)
127
- return buff.end;
128
- const last = bufferedRanges[bufferedRanges.length - 1];
129
- return last.end;
130
- }
131
- function isValidDuration(duration2) {
132
- if (duration2 && !Number.isNaN(duration2) && duration2 !== Number.POSITIVE_INFINITY && duration2 !== Number.NEGATIVE_INFINITY) {
133
- return true;
134
- }
135
- return false;
136
- }
137
- function destroy() {
138
- player?.pause();
139
- player?.remove();
140
- playerList.splice(playerList.indexOf(player), 1);
141
- player = null;
142
- }
143
- onMounted(() => {
144
- initialize();
145
- watch([source, options.type], () => {
146
- destroy();
147
- loaded.value = false;
148
- paused.value = true;
149
- currentTime.value = 0;
150
- duration.value = 0;
151
- initialize();
152
- });
153
- });
154
- onUnmounted(() => destroy());
155
- return {
156
- isSupported,
157
- paused,
158
- loaded,
159
- currentTime,
160
- duration,
161
- player,
162
- destroy,
163
- play: () => {
164
- if (options.mutex ?? true) {
165
- for (const p of playerList) {
166
- if (p !== player)
167
- p.pause();
168
- }
169
- }
170
- player?.play();
171
- },
172
- pause: () => player?.pause(),
173
- seek(time) {
174
- if (player)
175
- player.currentTime = time;
176
- },
177
- setVolume(volume2) {
178
- if (player)
179
- player.volume = Math.min(1, Math.max(0, volume2));
180
- }
181
- };
20
+ let player = null;
21
+ let unknownSupport = false;
22
+ const isSupported = ref(false);
23
+ const loaded = ref(false);
24
+ const paused = ref(true);
25
+ const currentTime = ref(0);
26
+ const duration = ref(0);
27
+ const volume = ref(1);
28
+ function initialize() {
29
+ player = document.createElement("audio");
30
+ player.className = "audio-player";
31
+ player.style.display = "none";
32
+ player.preload = options.autoplay ? "auto" : "none";
33
+ player.autoplay = options.autoplay ?? false;
34
+ document.body.appendChild(player);
35
+ playerList.push(player);
36
+ player.onloadedmetadata = () => {
37
+ duration.value = player.duration;
38
+ currentTime.value = player.currentTime;
39
+ volume.value = player.volume;
40
+ loaded.value = true;
41
+ };
42
+ player.oncanplay = (...args) => {
43
+ loaded.value = true;
44
+ if (unknownSupport) isSupported.value = true;
45
+ options.oncanplay?.bind(player)(...args);
46
+ };
47
+ player.onplay = (...args) => {
48
+ paused.value = false;
49
+ options.onplay?.bind(player)(...args);
50
+ };
51
+ player.onpause = (...args) => {
52
+ paused.value = true;
53
+ options.onpause?.bind(player)(...args);
54
+ };
55
+ player.ontimeupdate = () => {
56
+ if (isValidDuration(player.duration)) {
57
+ const lastBufferTime = getLastBufferedTime();
58
+ if (lastBufferTime <= player.duration) {
59
+ options.ontimeupdate?.bind(player)(lastBufferTime);
60
+ currentTime.value = lastBufferTime;
61
+ options.onprogress?.bind(player)(lastBufferTime, player.duration);
62
+ }
63
+ }
64
+ };
65
+ player.onvolumechange = () => {
66
+ volume.value = player.volume;
67
+ options.onvolume?.bind(player)(player.volume);
68
+ };
69
+ player.onended = (...args) => {
70
+ paused.value = true;
71
+ options.onend?.bind(player)(...args);
72
+ };
73
+ player.onplaying = options.onplaying;
74
+ player.onload = options.onload;
75
+ player.onerror = options.onerror;
76
+ player.onseeked = options.onseeked;
77
+ player.oncanplaythrough = options.oncanplaythrough;
78
+ player.onwaiting = options.onwaiting;
79
+ isSupported.value = isSupportType();
80
+ player.src = toValue(source);
81
+ player.load();
82
+ }
83
+ function isSupportType() {
84
+ if (!player) return false;
85
+ let type = toValue(options.type);
86
+ if (!type) {
87
+ const ext = toValue(source).split(".").pop() || "";
88
+ type = Object.keys(mimeTypes).filter((type$1) => mimeTypes[type$1].includes(ext))[0];
89
+ }
90
+ if (!type) {
91
+ unknownSupport = true;
92
+ return false;
93
+ }
94
+ const isSupported$1 = player.canPlayType(type) !== "";
95
+ if (!isSupported$1) console.warn(`The specified type "${type}" is not supported by the browser.`);
96
+ return isSupported$1;
97
+ }
98
+ function getBufferedRanges() {
99
+ if (!player) return [];
100
+ const ranges = [];
101
+ const seekable = player.buffered || [];
102
+ const offset = 0;
103
+ for (let i = 0, length = seekable.length; i < length; i++) {
104
+ let start = seekable.start(i);
105
+ let end = seekable.end(i);
106
+ if (!isValidDuration(start)) start = 0;
107
+ if (!isValidDuration(end)) {
108
+ end = 0;
109
+ continue;
110
+ }
111
+ ranges.push({
112
+ start: start + offset,
113
+ end: end + offset
114
+ });
115
+ }
116
+ return ranges;
117
+ }
118
+ function getLastBufferedTime() {
119
+ const bufferedRanges = getBufferedRanges();
120
+ if (!bufferedRanges.length) return 0;
121
+ const buff = bufferedRanges.find((buff$1) => buff$1.start < player.currentTime && buff$1.end > player.currentTime);
122
+ if (buff) return buff.end;
123
+ const last = bufferedRanges[bufferedRanges.length - 1];
124
+ return last.end;
125
+ }
126
+ function isValidDuration(duration$1) {
127
+ if (duration$1 && !Number.isNaN(duration$1) && duration$1 !== Number.POSITIVE_INFINITY && duration$1 !== Number.NEGATIVE_INFINITY) return true;
128
+ return false;
129
+ }
130
+ function destroy() {
131
+ player?.pause();
132
+ player?.remove();
133
+ playerList.splice(playerList.indexOf(player), 1);
134
+ player = null;
135
+ }
136
+ onMounted(() => {
137
+ initialize();
138
+ watch([source, options.type], () => {
139
+ destroy();
140
+ loaded.value = false;
141
+ paused.value = true;
142
+ currentTime.value = 0;
143
+ duration.value = 0;
144
+ initialize();
145
+ });
146
+ });
147
+ onUnmounted(() => destroy());
148
+ return {
149
+ isSupported,
150
+ paused,
151
+ loaded,
152
+ currentTime,
153
+ duration,
154
+ player,
155
+ destroy,
156
+ play: () => {
157
+ if (options.mutex ?? true) {
158
+ for (const p of playerList) if (p !== player) p.pause();
159
+ }
160
+ player?.play();
161
+ },
162
+ pause: () => player?.pause(),
163
+ seek(time) {
164
+ if (player) player.currentTime = time;
165
+ },
166
+ setVolume(volume$1) {
167
+ if (player) player.volume = Math.min(1, Math.max(0, volume$1));
168
+ }
169
+ };
182
170
  }
183
- export {
184
- useAudioPlayer
185
- };
171
+
172
+ //#endregion
173
+ export { useAudioPlayer };