open-webui/src/lib/components/chat/Messages/Markdown/MarkdownInlineTokens.svelte

76 lines
2.3 KiB
Svelte
Raw Normal View History

<script lang="ts">
import DOMPurify from 'dompurify';
2024-08-26 12:17:33 +00:00
import { toast } from 'svelte-sonner';
import type { Token } from 'marked';
2024-08-26 12:17:33 +00:00
import { getContext } from 'svelte';
const i18n = getContext('i18n');
2024-08-08 22:01:38 +00:00
2024-08-17 17:43:04 +00:00
import { WEBUI_BASE_URL } from '$lib/constants';
2024-08-26 12:17:33 +00:00
import { copyToClipboard, revertSanitizedResponseContent, unescapeHtml } from '$lib/utils';
import Image from '$lib/components/common/Image.svelte';
import KatexRenderer from './KatexRenderer.svelte';
2024-08-08 22:01:38 +00:00
export let id: string;
export let tokens: Token[];
</script>
{#each tokens as token}
{#if token.type === 'escape'}
{unescapeHtml(token.text)}
{:else if token.type === 'html'}
{@const html = DOMPurify.sanitize(token.text)}
2024-08-16 13:44:18 +00:00
{#if html && html.includes('<video')}
{@html html}
2024-08-16 15:51:50 +00:00
{:else if token.text.includes(`<iframe src="${WEBUI_BASE_URL}/api/v1/files/`)}
{@html `${token.text}`}
{:else}
{token.text}
{/if}
{:else if token.type === 'link'}
<a href={token.href} target="_blank" rel="nofollow" title={token.title}>{token.text}</a>
{:else if token.type === 'image'}
<Image src={token.href} alt={token.text} />
{:else if token.type === 'strong'}
<strong>
<svelte:self id={`${id}-strong`} tokens={token.tokens} />
</strong>
{:else if token.type === 'em'}
<em>
<svelte:self id={`${id}-em`} tokens={token.tokens} />
</em>
{:else if token.type === 'codespan'}
2024-08-26 12:17:33 +00:00
<!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
<code
class="codespan cursor-pointer"
on:click={() => {
copyToClipboard(unescapeHtml(token.text));
toast.success($i18n.t('Copied to clipboard'));
}}>{unescapeHtml(token.text)}</code
>
{:else if token.type === 'br'}
<br />
{:else if token.type === 'del'}
<del>
<svelte:self id={`${id}-del`} tokens={token.tokens} />
</del>
2024-08-08 22:01:38 +00:00
{:else if token.type === 'inlineKatex'}
{#if token.text}
2024-08-14 14:07:39 +00:00
<KatexRenderer content={revertSanitizedResponseContent(token.text)} displayMode={false} />
2024-08-08 22:01:38 +00:00
{/if}
2024-08-16 13:33:14 +00:00
{:else if token.type === 'iframe'}
<iframe
src="{WEBUI_BASE_URL}/api/v1/files/{token.fileId}/content"
title={token.fileId}
width="100%"
frameborder="0"
onload="this.style.height=(this.contentWindow.document.body.scrollHeight+20)+'px';"
></iframe>
{:else if token.type === 'text'}
2024-08-08 22:01:38 +00:00
{token.raw}
{/if}
{/each}