mirror of
https://github.com/open-webui/open-webui
synced 2025-06-26 18:26:48 +00:00
enh: html token (allow yt embed)
This commit is contained in:
parent
f4de3b4c45
commit
6fd082d55f
49
src/lib/components/chat/Messages/Markdown/HTMLToken.svelte
Normal file
49
src/lib/components/chat/Messages/Markdown/HTMLToken.svelte
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import DOMPurify from 'dompurify';
|
||||||
|
import type { Token } from 'marked';
|
||||||
|
|
||||||
|
import { WEBUI_BASE_URL } from '$lib/constants';
|
||||||
|
import Source from './Source.svelte';
|
||||||
|
|
||||||
|
export let id: string;
|
||||||
|
export let token: Token;
|
||||||
|
|
||||||
|
export let onSourceClick: Function = () => {};
|
||||||
|
|
||||||
|
let html: string | null = null;
|
||||||
|
|
||||||
|
$: if (token.type === 'html' && token?.text) {
|
||||||
|
html = DOMPurify.sanitize(token.text);
|
||||||
|
} else {
|
||||||
|
html = null;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if token.type === 'html'}
|
||||||
|
{#if html && html.includes('<video')}
|
||||||
|
{@html html}
|
||||||
|
{:else if token.text && token.text.match(/<iframe\s+[^>]*src="https:\/\/www\.youtube\.com\/embed\/([a-zA-Z0-9_-]{11})"[^>]*><\/iframe>/)}
|
||||||
|
{@const match = token.text.match(
|
||||||
|
/<iframe\s+[^>]*src="https:\/\/www\.youtube\.com\/embed\/([a-zA-Z0-9_-]{11})"[^>]*><\/iframe>/
|
||||||
|
)}
|
||||||
|
{@const ytId = match && match[1]}
|
||||||
|
{#if ytId}
|
||||||
|
<iframe
|
||||||
|
class="w-full aspect-video my-2"
|
||||||
|
src={`https://www.youtube.com/embed/${ytId}`}
|
||||||
|
title="YouTube video player"
|
||||||
|
frameborder="0"
|
||||||
|
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
|
||||||
|
referrerpolicy="strict-origin-when-cross-origin"
|
||||||
|
allowfullscreen
|
||||||
|
>
|
||||||
|
</iframe>
|
||||||
|
{/if}
|
||||||
|
{:else if token.text.includes(`<iframe src="${WEBUI_BASE_URL}/api/v1/files/`)}
|
||||||
|
{@html `${token.text}`}
|
||||||
|
{:else if token.text.includes(`<source_id`)}
|
||||||
|
<Source {id} {token} onClick={onSourceClick} />
|
||||||
|
{:else}
|
||||||
|
{token.text}
|
||||||
|
{/if}
|
||||||
|
{/if}
|
@ -13,6 +13,7 @@
|
|||||||
import Image from '$lib/components/common/Image.svelte';
|
import Image from '$lib/components/common/Image.svelte';
|
||||||
import KatexRenderer from './KatexRenderer.svelte';
|
import KatexRenderer from './KatexRenderer.svelte';
|
||||||
import Source from './Source.svelte';
|
import Source from './Source.svelte';
|
||||||
|
import HtmlToken from './HTMLToken.svelte';
|
||||||
|
|
||||||
export let id: string;
|
export let id: string;
|
||||||
export let tokens: Token[];
|
export let tokens: Token[];
|
||||||
@ -23,16 +24,7 @@
|
|||||||
{#if token.type === 'escape'}
|
{#if token.type === 'escape'}
|
||||||
{unescapeHtml(token.text)}
|
{unescapeHtml(token.text)}
|
||||||
{:else if token.type === 'html'}
|
{:else if token.type === 'html'}
|
||||||
{@const html = DOMPurify.sanitize(token.text)}
|
<HtmlToken {id} {token} {onSourceClick} />
|
||||||
{#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 {id} {token} onClick={onSourceClick} />
|
|
||||||
{:else}
|
|
||||||
{@html html}
|
|
||||||
{/if}
|
|
||||||
{:else if token.type === 'link'}
|
{:else if token.type === 'link'}
|
||||||
{#if token.tokens}
|
{#if token.tokens}
|
||||||
<a href={token.href} target="_blank" rel="nofollow" title={token.title}>
|
<a href={token.href} target="_blank" rel="nofollow" title={token.title}>
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
import Source from './Source.svelte';
|
import Source from './Source.svelte';
|
||||||
import { settings } from '$lib/stores';
|
import { settings } from '$lib/stores';
|
||||||
|
import HtmlToken from './HTMLToken.svelte';
|
||||||
|
|
||||||
export let id: string;
|
export let id: string;
|
||||||
export let tokens: Token[];
|
export let tokens: Token[];
|
||||||
@ -266,16 +267,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</Collapsible>
|
</Collapsible>
|
||||||
{:else if token.type === 'html'}
|
{:else if token.type === 'html'}
|
||||||
{@const html = DOMPurify.sanitize(token.text)}
|
<HtmlToken {id} {token} {onSourceClick} />
|
||||||
{#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 {id} {token} onClick={onSourceClick} />
|
|
||||||
{:else}
|
|
||||||
{token.text}
|
|
||||||
{/if}
|
|
||||||
{:else if token.type === 'iframe'}
|
{:else if token.type === 'iframe'}
|
||||||
<iframe
|
<iframe
|
||||||
src="{WEBUI_BASE_URL}/api/v1/files/{token.fileId}/content"
|
src="{WEBUI_BASE_URL}/api/v1/files/{token.fileId}/content"
|
||||||
|
Loading…
Reference in New Issue
Block a user