forked from misskey-dev/misskey-hub-next
-
Notifications
You must be signed in to change notification settings - Fork 0
/
NuxtLink.vue
53 lines (42 loc) · 1.55 KB
/
NuxtLink.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<template>
<NuxtLink
:to="realHref"
:href="undefined"
:target="realTarget"
>
<slot></slot>
</NuxtLink>
</template>
<script setup lang="ts">
import { cleanDoubleSlashes, withQuery, withTrailingSlash } from 'ufo';
import { isLocalPath, sanitizeInternalPath } from '@/assets/js/misc';
import type { RouteLocationRaw } from '#vue-router';
/**
* TrailingSlashをつけている(pnpm generate時の出力ディレクトリ構造の関係)ので、
* 二重にスラッシュが入って無限ループに陥らないようにするための
* NuxtLinkのラッパーコンポーネント
*/
const rawProps = defineProps<{
to?: RouteLocationRaw | string;
href?: RouteLocationRaw | string;
target?: unknown;
}>();
const localePath = useGLocalePath();
const needsToOpenExternally = ref(false);
const realHref = computed(() => {
const rhf = rawProps.to ?? rawProps.href;
if (rhf && typeof rhf === 'string') {
if (rhf.startsWith('x-mi-web://')) {
needsToOpenExternally.value = true;
return localePath(withQuery('/mi-web/', { path: cleanDoubleSlashes(rhf.replace('x-mi-web:/', '')) }));
}
if (isLocalPath(rhf)) {
return withTrailingSlash(cleanDoubleSlashes(sanitizeInternalPath(rhf)), true);
}
return rhf;
}
// TODO: ルート定義をオブジェクトで渡された時のバリデーション
return rhf;
});
const realTarget = computed(() => (needsToOpenExternally.value ? '_blank' : (rawProps.target ?? null)));
</script>