12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 |
- <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';
- 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'}
- {@const html = DOMPurify.sanitize(token.text)}
- {#if html && html.includes('<video')}
- {@html html}
- {:else if token.text.includes(`<iframe src="${WEBUI_BASE_URL}/api/v1/files/`)}
- {@html `${token.text}`}
- {:else if token.text.includes(`<source_id`)}
- <Source {token} onClick={onSourceClick} />
- {:else}
- {token.text}
- {/if}
- {: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}
|