관리자 레이아웃과 네비게이션 정리
This commit is contained in:
@@ -53,10 +53,24 @@ const imageSrc = computed(() => props.thumbnail || faviconUrl.value)
|
||||
* @returns {string}
|
||||
*/
|
||||
const displayTitle = computed(() => props.title || displayHost.value || props.url)
|
||||
|
||||
/**
|
||||
* 외부 링크로 열어도 되는 URL인지 확인한다.
|
||||
* @returns {boolean} 허용 여부
|
||||
*/
|
||||
const isSafeBookmarkUrl = computed(() => {
|
||||
try {
|
||||
const parsedUrl = new URL(props.url)
|
||||
return ['http:', 'https:'].includes(parsedUrl.protocol)
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a
|
||||
v-if="isSafeBookmarkUrl"
|
||||
class="prose-bookmark group prose-bookmark-card my-8 flex max-w-full flex-col overflow-hidden rounded-[10px] border border-[var(--site-line)] bg-[var(--site-panel)] no-underline transition-[background-color,box-shadow] hover:bg-[color-mix(in_srgb,var(--site-panel)_86%,var(--site-text)_14%)] sm:flex-row"
|
||||
:href="url"
|
||||
target="_blank"
|
||||
@@ -92,4 +106,7 @@ const displayTitle = computed(() => props.title || displayHost.value || props.ur
|
||||
</p>
|
||||
</div>
|
||||
</a>
|
||||
<p v-else class="prose-bookmark prose-bookmark-invalid my-8 rounded-[10px] border border-[var(--site-line)] bg-[var(--site-panel)] p-5 text-sm font-semibold text-[var(--site-muted)]">
|
||||
지원하지 않는 북마크 URL입니다.
|
||||
</p>
|
||||
</template>
|
||||
|
||||
@@ -63,6 +63,22 @@ const youtubeId = computed(() => getYouTubeId(props.url))
|
||||
const youtubeEmbedUrl = computed(() => youtubeId.value ? `https://www.youtube.com/embed/${youtubeId.value}` : '')
|
||||
const tweetId = computed(() => getTweetId(props.url))
|
||||
|
||||
/**
|
||||
* 외부 링크로 열어도 되는 URL인지 확인한다.
|
||||
* @param {string} value - 검사할 URL
|
||||
* @returns {boolean} 허용 여부
|
||||
*/
|
||||
const isSafeExternalUrl = (value) => {
|
||||
try {
|
||||
const parsedUrl = new URL(value)
|
||||
return ['http:', 'https:'].includes(parsedUrl.protocol)
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
const safeExternalUrl = computed(() => isSafeExternalUrl(props.url) ? props.url : '')
|
||||
|
||||
/**
|
||||
* Twitter 공식 embed iframe 주소
|
||||
* @returns {string}
|
||||
@@ -98,13 +114,16 @@ const tweetEmbedUrl = computed(() => {
|
||||
loading="lazy"
|
||||
/>
|
||||
<a
|
||||
v-else
|
||||
v-else-if="safeExternalUrl"
|
||||
class="prose-embed__link block p-5 text-sm font-semibold text-[var(--site-text)] hover:opacity-70"
|
||||
:href="url"
|
||||
:href="safeExternalUrl"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
{{ url }}
|
||||
</a>
|
||||
<p v-else class="prose-embed__invalid p-5 text-sm font-semibold text-[var(--site-muted)]">
|
||||
지원하지 않는 임베드 URL입니다.
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user