74 lines
2.0 KiB
Vue
74 lines
2.0 KiB
Vue
<template>
|
|
<component
|
|
:is="tag"
|
|
class="VPLink"
|
|
:class="{
|
|
link: props.href,
|
|
'lando': true,
|
|
'vp-external-link-icon': isExternal,
|
|
'no-icon': noIcon
|
|
}"
|
|
:href="getLink(props.href)"
|
|
:target="target ?? (isExternal ? '_blank' : isFauxInternal ? '_self' : undefined)"
|
|
:rel="relation ?? (isExternal ? 'noreferrer' : undefined)"
|
|
>
|
|
<slot />
|
|
</component>
|
|
</template>
|
|
|
|
<script setup>
|
|
import {useData} from 'vitepress';
|
|
import {computed} from 'vue';
|
|
import {normalizeLink} from 'vitepress/dist/client/theme-default/support/utils.js';
|
|
|
|
import {default as checkIsFauxInternal} from '../utils/is-faux-internal';
|
|
import {default as normalizeMvb} from '../utils/normalize-mvblink';
|
|
import {default as normalizeRoot} from '../utils/normalize-rootlink';
|
|
|
|
const EXTERNAL_URL_RE = /^(?:[a-z]+:|\/\/)/i;
|
|
|
|
const {theme, site} = useData();
|
|
const {internalDomains} = theme.value;
|
|
|
|
const props = defineProps({
|
|
tag: {
|
|
type: String,
|
|
default: undefined,
|
|
},
|
|
href: {
|
|
type: String,
|
|
default: undefined,
|
|
},
|
|
noIcon: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
target: {
|
|
type: String,
|
|
default: undefined,
|
|
},
|
|
rel: {
|
|
type: String,
|
|
default: undefined,
|
|
},
|
|
});
|
|
|
|
const relation = computed(() => {
|
|
if (props.rel === 'mvb') return 'alternate';
|
|
else if (props.rel === 'root' || props.rel === 'none') return undefined;
|
|
return props.rel;
|
|
});
|
|
const tag = computed(() => props.tag ?? (props.href ? 'a' : 'span'));
|
|
const target = computed(() => props.target ?? (props.rel === 'mvb' || props.rel === 'root' ? '_self' : undefined));
|
|
|
|
const isFauxInternal = computed(() => props.href && checkIsFauxInternal(props.href, internalDomains));
|
|
const isExternal = computed(() => !isFauxInternal.value && props.href && EXTERNAL_URL_RE.test(props.href));
|
|
|
|
const getLink = href => {
|
|
if (props.rel === 'mvb' && href) return normalizeMvb(href, site.value);
|
|
else if (props.rel === 'root' && href) return normalizeRoot(href, site.value);
|
|
return href ? normalizeLink(href) : undefined;
|
|
};
|
|
|
|
</script>
|