2023-07-11 19:19:32 +02:00
|
|
|
|
<script setup lang="ts">
|
2023-12-13 15:14:07 +01:00
|
|
|
|
import MiIco from '@/assets/svg/misskey_mi_bi.svg';
|
2023-07-13 17:38:17 +02:00
|
|
|
|
import ExtIco from 'bi/box-arrow-up-right.svg';
|
2023-12-30 05:16:36 +01:00
|
|
|
|
import { parseURL, isRelative, joinURL } from 'ufo';
|
2023-11-25 17:48:16 +01:00
|
|
|
|
import { isLocalPath, sanitizeInternalPath } from '@/assets/js/misc';
|
2023-07-13 17:38:17 +02:00
|
|
|
|
|
2023-07-11 19:19:32 +02:00
|
|
|
|
const runtimeConfig = useRuntimeConfig();
|
2023-12-30 05:16:36 +01:00
|
|
|
|
const rootDomain = parseURL(runtimeConfig.public.baseUrl);
|
2023-09-23 11:17:13 +02:00
|
|
|
|
const { resolve } = useRouter();
|
2023-12-30 05:29:37 +01:00
|
|
|
|
const route = useRoute();
|
2023-12-22 15:53:24 +01:00
|
|
|
|
const localePath = useGLocalePath();
|
2023-07-11 19:19:32 +02:00
|
|
|
|
|
|
|
|
|
const props = defineProps({
|
|
|
|
|
href: {
|
|
|
|
|
type: String,
|
|
|
|
|
default: ''
|
|
|
|
|
},
|
|
|
|
|
target: {
|
|
|
|
|
type: String,
|
|
|
|
|
default: undefined,
|
|
|
|
|
required: false
|
2023-07-15 10:32:48 +02:00
|
|
|
|
},
|
2023-07-11 19:19:32 +02:00
|
|
|
|
})
|
|
|
|
|
|
2023-09-23 11:17:13 +02:00
|
|
|
|
const realHref = ref(props.href);
|
|
|
|
|
const realTarget = ref(props.target);
|
2023-07-11 19:19:32 +02:00
|
|
|
|
|
2023-12-30 05:16:36 +01:00
|
|
|
|
const url = parseURL(realHref.value);
|
2024-01-30 05:03:22 +01:00
|
|
|
|
let pathDetermined = false;
|
2023-12-13 15:14:07 +01:00
|
|
|
|
|
2023-11-25 17:48:16 +01:00
|
|
|
|
if (isLocalPath(realHref.value)) {
|
2023-12-30 05:16:36 +01:00
|
|
|
|
// 相対パスの場合(trailing slashがあるので1つくり下げる)
|
2023-12-30 05:29:37 +01:00
|
|
|
|
if (isRelative(realHref.value) && route.meta.__isDocsIndexPage !== true) {
|
2023-12-30 05:16:36 +01:00
|
|
|
|
realHref.value = joinURL('../', realHref.value.replace(/^\.\//, ''));
|
2024-01-30 05:03:22 +01:00
|
|
|
|
const resolved = resolve(realHref.value);
|
|
|
|
|
if (resolved.name && resolved.name.toString().includes('___')) {
|
|
|
|
|
// 相対パスがすでにローカライズされたパスの場合は以降の処理をスキップ
|
|
|
|
|
pathDetermined = true;
|
|
|
|
|
}
|
2023-12-30 05:16:36 +01:00
|
|
|
|
}
|
|
|
|
|
|
2024-01-30 05:03:22 +01:00
|
|
|
|
if (!pathDetermined) {
|
|
|
|
|
// 内部リンクの場合
|
|
|
|
|
if (/^\/[a-z]{2}\//.test(realHref.value)) {
|
|
|
|
|
realHref.value = sanitizeInternalPath(realHref.value);
|
|
|
|
|
} else {
|
|
|
|
|
// 渡されたパスがローカライズされたルートでない場合はローカライズされたパスを返す
|
|
|
|
|
realHref.value = sanitizeInternalPath(localePath(resolve(realHref.value).fullPath));
|
|
|
|
|
}
|
2023-07-11 19:19:32 +02:00
|
|
|
|
}
|
2023-09-23 11:17:13 +02:00
|
|
|
|
} else if (rootDomain.host !== url.host) {
|
|
|
|
|
realTarget.value = '_blank';
|
2023-07-11 19:19:32 +02:00
|
|
|
|
}
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<template>
|
2023-12-24 16:57:53 +01:00
|
|
|
|
<GNuxtLink :href="realHref" :target="realTarget">
|
2023-12-13 15:14:07 +01:00
|
|
|
|
<slot></slot>
|
|
|
|
|
<MiIco v-if="realHref.startsWith('x-mi-web://')" class="text-xs mx-1" />
|
|
|
|
|
<ExtIco v-else-if="realTarget === '_blank'" class="text-xs mx-1" />
|
2023-07-11 19:19:32 +02:00
|
|
|
|
</GNuxtLink>
|
|
|
|
|
</template>
|