forked from open-webui/open-webui
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathHTMLToken.svelte
More file actions
125 lines (116 loc) · 3.69 KB
/
Copy pathHTMLToken.svelte
File metadata and controls
125 lines (116 loc) · 3.69 KB
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
<script lang="ts">
import DOMPurify from 'dompurify';
import type { Token } from 'marked';
import { WEBUI_BASE_URL } from '$lib/constants';
import Source from './Source.svelte';
import { settings } from '$lib/stores';
import { getSafeGenericIframeSrc } from '$lib/utils/iframe';
export let id: string;
export let token: Token;
export let onSourceClick: Function = () => {};
let html: string | null = null;
let genericIframeSrc: string | null = null;
$: if (token.type === 'html' && token?.text) {
html = DOMPurify.sanitize(token.text);
genericIframeSrc = getSafeGenericIframeSrc(token.text);
} else {
html = null;
genericIframeSrc = null;
}
const resizeIframeToContent = (event: Event) => {
const iframe = event.currentTarget as HTMLIFrameElement | null;
try {
const scrollHeight = iframe?.contentWindow?.document?.body?.scrollHeight;
if (iframe && scrollHeight) {
iframe.style.height = `${scrollHeight + 20}px`;
}
} catch {
// Cross-origin or strictly sandboxed iframes cannot expose their document.
}
};
</script>
{#if token.type === 'html'}
{#if html && html.includes('<video')}
{@const video = html.match(/<video[^>]*>([\s\S]*?)<\/video>/)}
{@const videoSrc = video && video[1]}
{#if videoSrc}
<!-- svelte-ignore a11y-media-has-caption -->
<video
class="w-full my-2"
src={videoSrc.replaceAll('&', '&')}
title="Video player"
frameborder="0"
referrerpolicy="strict-origin-when-cross-origin"
controls
allowfullscreen
></video>
{:else}
{token.text}
{/if}
{:else if html && html.includes('<audio')}
{@const audio = html.match(/<audio[^>]*>([\s\S]*?)<\/audio>/)}
{@const audioSrc = audio && audio[1]}
{#if audioSrc}
<!-- svelte-ignore a11y-media-has-caption -->
<audio
class="w-full my-2"
src={audioSrc.replaceAll('&', '&')}
title="Audio player"
controls
></audio>
{:else}
{token.text}
{/if}
{: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 genericIframeSrc}
<iframe
class="w-full my-2"
src={genericIframeSrc}
title="Embedded content"
frameborder="0"
sandbox=""
referrerpolicy="strict-origin-when-cross-origin"
on:load={resizeIframeToContent}
></iframe>
{:else if token.text && token.text.includes('<iframe')}
{token.text}
{:else if token.text.includes(`<file type="html"`)}
{@const match = token.text.match(/<file type="html" id="([^"]+)"/)}
{@const fileId = match && match[1]}
{#if fileId}
<iframe
class="w-full my-2"
src={`${WEBUI_BASE_URL}/api/v1/files/${fileId}/content/html`}
title="Content"
frameborder="0"
sandbox="allow-scripts allow-downloads{($settings?.iframeSandboxAllowForms ?? false)
? ' allow-forms'
: ''}{($settings?.iframeSandboxAllowSameOrigin ?? false) ? ' allow-same-origin' : ''}"
referrerpolicy="strict-origin-when-cross-origin"
allowfullscreen
width="100%"
on:load={resizeIframeToContent}
></iframe>
{/if}
{:else if token.text.includes(`<source_id`)}
<Source {id} {token} onClick={onSourceClick} />
{:else}
{token.text}
{/if}
{/if}