feat: clean shared link in the parsed html if conditions are met
This commit is contained in:
parent
0b3d32e821
commit
075a9d115b
@ -5,15 +5,29 @@ const {
|
||||
status,
|
||||
newer,
|
||||
withAction = true,
|
||||
cleanSharedLink,
|
||||
} = defineProps<{
|
||||
status: mastodon.v1.Status | mastodon.v1.StatusEdit
|
||||
newer?: mastodon.v1.Status
|
||||
withAction?: boolean
|
||||
cleanSharedLink?: string | false
|
||||
}>()
|
||||
|
||||
const { translation } = useTranslation(status, getLanguageCode())
|
||||
|
||||
const emojisObject = useEmojisFallback(() => status.emojis)
|
||||
|
||||
/**
|
||||
* example status raw content
|
||||
*
|
||||
* <p>🔴 trying to code live - come let's talk <span class="h-card"><a href="https://m.webtoo.ls/@elk" class="u-url mention">@<span>elk</span></a></span> and <a href="https://social.ayco.io/tags/opensource" class="mention hashtag" rel="tag">#<span>opensource</span></a> <a href="https://www.twitch.tv/ayoayco" target="_blank" rel="nofollow noopener noreferrer"><span class="invisible">https://www.</span><span class="">twitch.tv/ayoayco</span><span class="invisible"></span></a></p>
|
||||
*
|
||||
*
|
||||
* "<p>I say something about the link first</p><p><a href=\"https://ayco.io\" target=\"_blank\" rel=\"nofollow noopener noreferrer\"><span class=\"invisible\">https://</span><span class=\"\">ayco.io</span><span class=\"invisible\"></span></a></p>"
|
||||
|
||||
*
|
||||
*/
|
||||
|
||||
const vnode = $computed(() => {
|
||||
if (!status.content)
|
||||
return null
|
||||
@ -24,7 +38,9 @@ const vnode = $computed(() => {
|
||||
collapseMentionLink: !!('inReplyToId' in status && status.inReplyToId),
|
||||
status: 'id' in status ? status : undefined,
|
||||
inReplyToStatus: newer,
|
||||
cleanSharedLink,
|
||||
})
|
||||
|
||||
return vnode
|
||||
})
|
||||
</script>
|
||||
|
@ -16,6 +16,10 @@ const filter = $computed(() => filterResult?.filter)
|
||||
|
||||
const filterPhrase = $computed(() => filter?.title)
|
||||
const isFiltered = $computed(() => filterPhrase && (context && context !== 'details' ? filter?.context.includes(context) : false))
|
||||
|
||||
const cleanSharedLink = !status.poll
|
||||
&& !status.mediaAttachments.length
|
||||
&& status.card?.url
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@ -34,7 +38,7 @@ const isFiltered = $computed(() => filterPhrase && (context && context !== 'deta
|
||||
<template v-else-if="status.spoilerText" #spoiler>
|
||||
<p>{{ status.spoilerText }}</p>
|
||||
</template>
|
||||
<StatusBody v-if="!status.sensitive || status.spoilerText" :status="status" :newer="newer" :with-action="!isDetails" :class="isDetails ? 'text-xl' : ''" />
|
||||
<StatusBody v-if="!status.sensitive || status.spoilerText" :clean-shared-link="cleanSharedLink" :status="status" :newer="newer" :with-action="!isDetails" :class="isDetails ? 'text-xl' : ''" />
|
||||
<StatusTranslation :status="status" />
|
||||
<StatusPoll v-if="status.poll" :status="status" />
|
||||
<StatusMedia
|
||||
@ -45,6 +49,7 @@ const isFiltered = $computed(() => filterPhrase && (context && context !== 'deta
|
||||
v-if="status.card"
|
||||
:card="status.card"
|
||||
:small-picture-only="status.mediaAttachments?.length > 0"
|
||||
:clean-shared-link="cleanSharedLink"
|
||||
/>
|
||||
<StatusCard
|
||||
v-if="status.reblog"
|
||||
|
@ -7,15 +7,16 @@ const props = defineProps<{
|
||||
smallPictureOnly?: boolean
|
||||
/** When it is root card in the list, not appear as a child card */
|
||||
root?: boolean
|
||||
/** Defined when the preview card URL matches the last shared link href attribute */
|
||||
cleanSharedLink?: string
|
||||
}>()
|
||||
|
||||
const providerName = $computed(() => props.card.providerName ? props.card.providerName : new URL(props.card.url).hostname)
|
||||
|
||||
const gitHubCards = $(usePreferences('experimentalGitHubCards'))
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<LazyStatusPreviewGitHub v-if="gitHubCards && providerName === 'GitHub'" :card="card" />
|
||||
<LazyStatusPreviewStackBlitz v-else-if="gitHubCards && providerName === 'stackblitz.com'" :card="card" :small-picture-only="smallPictureOnly" :root="root" />
|
||||
<StatusPreviewCardNormal v-else :card="card" :small-picture-only="smallPictureOnly" :root="root" />
|
||||
<StatusPreviewCardNormal v-else :card="card" :clean-shared-link="cleanSharedLink" :small-picture-only="smallPictureOnly" :root="root" />
|
||||
</template>
|
||||
|
@ -7,6 +7,8 @@ const props = defineProps<{
|
||||
smallPictureOnly?: boolean
|
||||
/** When it is root card in the list, not appear as a child card */
|
||||
root?: boolean
|
||||
/** Defined when the preview card URL matches the last shared link href attribute */
|
||||
cleanSharedLink?: string
|
||||
}>()
|
||||
|
||||
// mastodon's default max og image width
|
||||
@ -19,7 +21,7 @@ const isSquare = $computed(() => (
|
||||
|| Number(props.card.width || 0) < ogImageWidth
|
||||
|| Number(props.card.height || 0) < ogImageWidth / 2
|
||||
))
|
||||
const providerName = $computed(() => props.card.providerName ? props.card.providerName : new URL(props.card.url).hostname)
|
||||
const providerName = $computed(() => props.card.providerName ? `${props.card.providerName} · ${props.cleanSharedLink}` : new URL(props.card.url).hostname)
|
||||
|
||||
// TODO: handle card.type: 'photo' | 'video' | 'rich';
|
||||
const cardTypeIconMap: Record<mastodon.v1.PreviewCardType, string> = {
|
||||
|
@ -16,6 +16,7 @@ export interface ContentParseOptions {
|
||||
collapseMentionLink?: boolean
|
||||
status?: mastodon.v1.Status
|
||||
inReplyToStatus?: mastodon.v1.Status
|
||||
cleanSharedLink?: string | false // this is defined when conditions for cleaning the link are met
|
||||
}
|
||||
|
||||
const sanitizerBasicClasses = filterClasses(/^(h-\S*|p-\S*|u-\S*|dt-\S*|e-\S*|mention|hashtag|ellipsis|invisible)$/u)
|
||||
@ -84,6 +85,7 @@ export function parseMastodonHTML(
|
||||
mentions,
|
||||
status,
|
||||
inReplyToStatus,
|
||||
cleanSharedLink,
|
||||
} = options
|
||||
|
||||
if (markdown) {
|
||||
@ -127,7 +129,23 @@ export function parseMastodonHTML(
|
||||
if (collapseMentionLink)
|
||||
transforms.push(transformCollapseMentions(status, inReplyToStatus))
|
||||
|
||||
return transformSync(parse(html), transforms)
|
||||
const node = parse(html) as Node
|
||||
|
||||
if (cleanSharedLink) {
|
||||
const filteredNode = node.children.filter(child => !!child.children) // remove invisible spans
|
||||
const filteredLength = filteredNode.length
|
||||
const length = filteredNode[filteredLength - 1].children.length
|
||||
const lastChild = filteredNode[filteredLength - 1].children[length - 1]
|
||||
const sharedHref = lastChild.attributes?.href
|
||||
const match = sharedHref === cleanSharedLink
|
||||
|
||||
if (match) {
|
||||
const index = length - 1
|
||||
filteredNode[filteredLength - 1].children.splice(index, 1)
|
||||
}
|
||||
}
|
||||
|
||||
return transformSync(node, transforms)
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user