File size: 2,496 Bytes
bc27e65
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
<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';



	export let id: string;

	export let tokens: Token[];

	export let onSourceClick: Function = () => {};

</script>

{#each tokens as token}
	{#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} />
			</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'}
		<!-- 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} {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"

			onload="this.style.height=(this.contentWindow.document.body.scrollHeight+20)+'px';"

		></iframe>
	{:else if token.type === 'text'}
		{token.raw}
	{/if}
{/each}