2023-09-23 11:17:13 +02:00
|
|
|
|
<template>
|
2023-09-23 12:07:45 +02:00
|
|
|
|
<NuxtLink
|
|
|
|
|
:to="realHref"
|
2023-09-23 20:02:14 +02:00
|
|
|
|
:href="undefined"
|
2023-12-13 15:14:07 +01:00
|
|
|
|
:target="realTarget"
|
2023-09-23 12:07:45 +02:00
|
|
|
|
>
|
2023-09-23 11:17:13 +02:00
|
|
|
|
<slot></slot>
|
2023-09-23 12:07:45 +02:00
|
|
|
|
</NuxtLink>
|
2023-09-23 11:17:13 +02:00
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
2023-12-13 15:14:07 +01:00
|
|
|
|
import { cleanDoubleSlashes, withQuery, withTrailingSlash } from 'ufo';
|
2023-11-25 17:48:16 +01:00
|
|
|
|
import { isLocalPath, sanitizeInternalPath } from '@/assets/js/misc';
|
2023-10-29 14:18:36 +01:00
|
|
|
|
import type { RouteLocationRaw } from '#vue-router';
|
2023-09-23 11:17:13 +02:00
|
|
|
|
|
2023-09-24 05:58:17 +02:00
|
|
|
|
/**
|
|
|
|
|
* TrailingSlashをつけている(pnpm generate時の出力ディレクトリ構造の関係)ので、
|
|
|
|
|
* 二重にスラッシュが入って無限ループに陥らないようにするための
|
|
|
|
|
* NuxtLinkのラッパーコンポーネント
|
|
|
|
|
*/
|
|
|
|
|
|
2023-09-23 20:02:14 +02:00
|
|
|
|
const rawProps = defineProps<{
|
|
|
|
|
to?: RouteLocationRaw | string;
|
|
|
|
|
href?: RouteLocationRaw | string;
|
2023-12-13 15:14:07 +01:00
|
|
|
|
target?: unknown;
|
2023-09-23 20:02:14 +02:00
|
|
|
|
}>();
|
2023-09-23 11:17:13 +02:00
|
|
|
|
|
2023-12-13 15:14:07 +01:00
|
|
|
|
const localePath = useLocalePath();
|
|
|
|
|
|
|
|
|
|
const needsToOpenExternally = ref(false);
|
2023-09-24 05:35:58 +02:00
|
|
|
|
const realHref = computed(() => {
|
|
|
|
|
const rhf = rawProps.to ?? rawProps.href;
|
2023-09-23 12:07:45 +02:00
|
|
|
|
|
2023-09-24 05:35:58 +02:00
|
|
|
|
if (rhf && typeof rhf === 'string') {
|
2023-12-13 15:14:07 +01:00
|
|
|
|
if (rhf.startsWith('x-mi-web://')) {
|
|
|
|
|
needsToOpenExternally.value = true;
|
|
|
|
|
return localePath(withQuery('/mi-web/', { path: cleanDoubleSlashes(rhf.replace('x-mi-web:/', '')) }));
|
|
|
|
|
}
|
2023-09-24 05:35:58 +02:00
|
|
|
|
|
2023-09-26 14:57:26 +02:00
|
|
|
|
if (isLocalPath(rhf)) {
|
2023-11-25 17:48:16 +01:00
|
|
|
|
return withTrailingSlash(cleanDoubleSlashes(sanitizeInternalPath(rhf)), true);
|
2023-09-24 05:35:58 +02:00
|
|
|
|
}
|
2023-09-23 11:17:13 +02:00
|
|
|
|
|
2023-09-24 05:58:17 +02:00
|
|
|
|
return rhf;
|
2023-09-24 05:35:58 +02:00
|
|
|
|
}
|
2023-09-24 05:39:32 +02:00
|
|
|
|
|
2023-09-24 05:58:17 +02:00
|
|
|
|
// TODO: ルート定義をオブジェクトで渡された時のバリデーション
|
|
|
|
|
|
2023-09-24 05:39:32 +02:00
|
|
|
|
return rhf;
|
2023-09-24 05:35:58 +02:00
|
|
|
|
});
|
2023-09-23 11:17:13 +02:00
|
|
|
|
|
2023-12-13 15:14:07 +01:00
|
|
|
|
const realTarget = computed(() => (needsToOpenExternally.value ? '_blank' : (rawProps.target ?? null)));
|
2023-09-23 11:17:13 +02:00
|
|
|
|
</script>
|