mirror of
https://github.com/open-webui/open-webui.git
synced 2025-12-12 04:15:25 +00:00
87 lines
3 KiB
Svelte
87 lines
3 KiB
Svelte
<script lang="ts">
|
|
import DOMPurify from 'dompurify';
|
|
import { toast } from 'svelte-sonner';
|
|
|
|
import type { Token } from 'marked';
|
|
import { getContext } from 'svelte';
|
|
|
|
const i18n = getContext('i18n');
|
|
|
|
import { WEBUI_BASE_URL } from '$lib/constants';
|
|
import { copyToClipboard, unescapeHtml } from '$lib/utils';
|
|
|
|
import Image from '$lib/components/common/Image.svelte';
|
|
import KatexRenderer from './KatexRenderer.svelte';
|
|
import Source from './Source.svelte';
|
|
import HtmlToken from './HTMLToken.svelte';
|
|
import TextToken from './MarkdownInlineTokens/TextToken.svelte';
|
|
import CodespanToken from './MarkdownInlineTokens/CodespanToken.svelte';
|
|
import MentionToken from './MarkdownInlineTokens/MentionToken.svelte';
|
|
import SourceToken from './SourceToken.svelte';
|
|
|
|
export let id: string;
|
|
export let done = true;
|
|
export let tokens: Token[];
|
|
export let sourceIds = [];
|
|
export let onSourceClick: Function = () => {};
|
|
</script>
|
|
|
|
{#each tokens as token, tokenIdx (tokenIdx)}
|
|
{#if token.type === 'escape'}
|
|
{unescapeHtml(token.text)}
|
|
{:else if token.type === 'html'}
|
|
<HtmlToken {id} {token} {onSourceClick} />
|
|
{:else if token.type === 'link'}
|
|
{#if token.tokens}
|
|
<a href={token.href} target="_blank" rel="nofollow" title={token.title}>
|
|
<svelte:self id={`${id}-a`} tokens={token.tokens} {onSourceClick} {done} />
|
|
</a>
|
|
{:else}
|
|
<a href={token.href} target="_blank" rel="nofollow" title={token.title}>{token.text}</a>
|
|
{/if}
|
|
{: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} {onSourceClick} /></strong>
|
|
{:else if token.type === 'em'}
|
|
<em><svelte:self id={`${id}-em`} tokens={token.tokens} {onSourceClick} /></em>
|
|
{:else if token.type === 'codespan'}
|
|
<CodespanToken {token} {done} />
|
|
{:else if token.type === 'br'}
|
|
<br />
|
|
{:else if token.type === 'del'}
|
|
<del><svelte:self id={`${id}-del`} tokens={token.tokens} {onSourceClick} /></del>
|
|
{:else if token.type === 'inlineKatex'}
|
|
{#if token.text}
|
|
<KatexRenderer content={token.text} displayMode={false} />
|
|
{/if}
|
|
{:else if token.type === 'iframe'}
|
|
<iframe
|
|
src="{WEBUI_BASE_URL}/api/v1/files/{token.fileId}/content"
|
|
title={token.fileId}
|
|
width="100%"
|
|
frameborder="0"
|
|
on:load={(e) => {
|
|
try {
|
|
e.currentTarget.style.height =
|
|
e.currentTarget.contentWindow.document.body.scrollHeight + 20 + 'px';
|
|
} catch {}
|
|
}}
|
|
></iframe>
|
|
{:else if token.type === 'mention'}
|
|
<MentionToken {token} />
|
|
{:else if token.type === 'footnote'}
|
|
{@html DOMPurify.sanitize(
|
|
`<sup class="footnote-ref footnote-ref-text">${token.escapedText}</sup>`
|
|
) || ''}
|
|
{:else if token.type === 'citation'}
|
|
<SourceToken {id} {token} {sourceIds} onClick={onSourceClick} />
|
|
<!-- {#if token.ids && token.ids.length > 0}
|
|
{#each token.ids as sourceId}
|
|
<Source id={sourceId - 1} title={sourceIds[sourceId - 1]} onClick={onSourceClick} />
|
|
{/each}
|
|
{/if} -->
|
|
{:else if token.type === 'text'}
|
|
<TextToken {token} {done} />
|
|
{/if}
|
|
{/each}
|