Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
chenpangpang
open-webui
Commits
7d42a791
Commit
7d42a791
authored
Aug 05, 2024
by
Timothy J. Baek
Browse files
refac: token rendering
parent
05bbca5b
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
90 additions
and
41 deletions
+90
-41
src/lib/components/chat/Messages/HTMLRenderer.svelte
src/lib/components/chat/Messages/HTMLRenderer.svelte
+30
-0
src/lib/components/chat/Messages/TokenRenderer.svelte
src/lib/components/chat/Messages/TokenRenderer.svelte
+58
-39
src/lib/components/common/Image.svelte
src/lib/components/common/Image.svelte
+2
-2
No files found.
src/lib/components/chat/Messages/HTMLRenderer.svelte
0 → 100644
View file @
7d42a791
<script lang="ts">
import Image from '$lib/components/common/Image.svelte';
import CodeBlock from './CodeBlock.svelte';
/* The html content of the tag */
export let html; //: string;
let parsedHTML = [html];
export let images;
export let codes;
// all images are in {{IMAGE_0}}, {{IMAGE_1}}.... format
// all codes are in {{CODE_0}}, {{CODE_1}}.... format
const rules = [];
rules.forEach((rule) => {
parsedHTML = parsedHTML.map((substr) => substr.split(rule.regex)).flat();
});
</script>
{#each parsedHTML as part}
{@const match = rules.find((rule) => rule.regex.test(part))}
{#if match}
<svelte:component this={match.component} {...match.props}>
{@html part}
</svelte:component>
{:else}
{@html part}
{/if}
{/each}
src/lib/components/chat/Messages/TokenRenderer.svelte
View file @
7d42a791
...
@@ -10,6 +10,9 @@
...
@@ -10,6 +10,9 @@
export let tokenIdx = 0;
export let tokenIdx = 0;
export let id;
export let id;
let element;
let content;
const renderer = new marked.Renderer();
const renderer = new marked.Renderer();
// For code blocks with simple backticks
// For code blocks with simple backticks
...
@@ -17,30 +20,19 @@
...
@@ -17,30 +20,19 @@
return `<code>${code.replaceAll('&', '&')}</code>`;
return `<code>${code.replaceAll('&', '&')}</code>`;
};
};
// renderer.code = (code, lang) => {
let codes = [];
// const element = document.createElement('div');
renderer.code = (code, lang) => {
// new CodeBlock({
codes.push({ code, lang, id: codes.length });
// target: element,
codes = codes;
// props: {
return `{{@CODE ${codes.length - 1}}}`;
// id: `${id}-${tokenIdx}`,
};
// lang: lang ?? '',
// code: revertSanitizedResponseContent(code ?? '')
// }
// });
// return element.innerHTML;
// };
// renderer.image = (href, title, text) => {
let images = [];
// const element = document.createElement('pre');
renderer.image = (href, title, text) => {
// new Image({
images.push({ href, title, text });
// target: element,
images = images;
// props: {
return `{{@IMAGE ${images.length - 1}}}`;
// src: href,
};
// alt: text
// }
// });
// return element.innerHTML;
// };
// Open all links in a new tab/window (from https://github.com/markedjs/marked/issues/655#issuecomment-383226346)
// Open all links in a new tab/window (from https://github.com/markedjs/marked/issues/655#issuecomment-383226346)
const origLinkRenderer = renderer.link;
const origLinkRenderer = renderer.link;
...
@@ -53,9 +45,23 @@
...
@@ -53,9 +45,23 @@
// eslint-disable-next-line @typescript-eslint/no-explicit-any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
extensions: any;
extensions: any;
};
};
$: if (token) {
images = [];
codes = [];
content = marked
.parse(token.raw, {
...defaults,
gfm: true,
breaks: true,
renderer
})
.split(/({{@IMAGE [^}]+}}|{{@CODE [^}]+}})/g);
}
</script>
</script>
{#if token.type === 'code'}
<div bind:this={element}>
{#if token.type === 'code'}
{#if token.lang === 'mermaid'}
{#if token.lang === 'mermaid'}
<pre class="mermaid">{revertSanitizedResponseContent(token.text)}</pre>
<pre class="mermaid">{revertSanitizedResponseContent(token.text)}</pre>
{:else}
{:else}
...
@@ -65,11 +71,24 @@
...
@@ -65,11 +71,24 @@
code={revertSanitizedResponseContent(token?.text ?? '')}
code={revertSanitizedResponseContent(token?.text ?? '')}
/>
/>
{/if}
{/if}
{:else}
{:else if token.type === 'image'}
{@html marked.parse(token.raw, {
<Image src={token.href} alt={token.text} />
...defaults,
{:else}
gfm: true,
{#each content as part}
breaks: true,
{@html part.startsWith('{{@IMAGE ') || part.startsWith('{{@CODE ') ? '' : part}
renderer
})}
{#if images.length > 0 && part.startsWith('{{@IMAGE ')}
{/if}
{@const img = images[parseInt(part.match(/{{@IMAGE (\d+)}}/)[1])]}
<div class="mt-6">
<Image src={img.href} text={img.text} />
</div>
{:else if codes.length > 0 && part.startsWith('{{@CODE ')}
{@const _code = codes[parseInt(part.match(/{{@CODE (\d+)}}/)[1])]}
<div class="my-10 -mb-6">
<CodeBlock id={`${id}-${tokenIdx}-${_code.id}`} lang={_code.lang} code={_code.code} />
</div>
{/if}
{/each}
{/if}
</div>
src/lib/components/common/Image.svelte
View file @
7d42a791
...
@@ -12,14 +12,14 @@
...
@@ -12,14 +12,14 @@
let showImagePreview = false;
let showImagePreview = false;
</script>
</script>
<div
class="w-full py-3"
>
<div>
<button
<button
on:click={() => {
on:click={() => {
showImagePreview = true;
showImagePreview = true;
}}
}}
class="w-full"
>
>
<img src={_src} {alt} class=" max-h-96 rounded-lg" draggable="false" data-cy="image" />
<img src={_src} {alt} class=" max-h-96 rounded-lg" draggable="false" data-cy="image" />
</button>
</button>
</div>
</div>
<ImagePreview bind:show={showImagePreview} src={_src} {alt} />
<ImagePreview bind:show={showImagePreview} src={_src} {alt} />
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment