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
e6b3de31
Commit
e6b3de31
authored
Aug 07, 2024
by
Timothy J. Baek
Browse files
refac
parent
7cbc9459
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
100 additions
and
38 deletions
+100
-38
src/lib/components/chat/Messages/MarkdownTokens.svelte
src/lib/components/chat/Messages/MarkdownTokens.svelte
+91
-24
src/lib/components/common/Image.svelte
src/lib/components/common/Image.svelte
+9
-14
No files found.
src/lib/components/chat/Messages/MarkdownTokens.svelte
View file @
e6b3de31
...
@@ -2,14 +2,20 @@
...
@@ -2,14 +2,20 @@
import { marked } from 'marked';
import { marked } from 'marked';
import type { Token } from 'marked';
import type { Token } from 'marked';
import { revertSanitizedResponseContent, unescapeHtml } from '$lib/utils';
import { revertSanitizedResponseContent, unescapeHtml } from '$lib/utils';
import CodeBlock from '$lib/components/chat/Messages/CodeBlock.svelte';
import { onMount } from 'svelte';
import { onMount } from 'svelte';
import Image from '$lib/components/common/Image.svelte';
import CodeBlock from '$lib/components/chat/Messages/CodeBlock.svelte';
import MarkdownInlineTokens from '$lib/components/chat/Messages/MarkdownInlineTokens.svelte';
import MarkdownInlineTokens from '$lib/components/chat/Messages/MarkdownInlineTokens.svelte';
export let id: string;
export let id: string;
export let tokens: Token[];
export let tokens: Token[];
export let top = true;
export let top = true;
let containerElement;
const headerComponent = (depth: number) => {
const headerComponent = (depth: number) => {
return 'h' + depth;
return 'h' + depth;
};
};
...
@@ -20,8 +26,61 @@
...
@@ -20,8 +26,61 @@
return `<code class="codespan">${code.replaceAll('&', '&')}</code>`;
return `<code class="codespan">${code.replaceAll('&', '&')}</code>`;
};
};
let codes = [];
renderer.code = (code, lang) => {
renderer.code = (code, lang) => {
return `<pre><code class="language-${lang}">${code}</code></pre>`;
codes.push({
code: code,
lang: lang
});
codes = codes;
const codeId = `${id}-${codes.length}`;
const interval = setInterval(() => {
if (document.getElementById(`code-${codeId}`)) {
clearInterval(interval);
new CodeBlock({
target: document.getElementById(`code-${codeId}`),
props: {
id: `${id}-${codes.length}`,
lang: lang,
code: revertSanitizedResponseContent(code)
},
hydrate: true,
$$inline: true
});
}
}, 10);
return `<div id="code-${id}-${codes.length}" />`;
};
let images = [];
renderer.image = (href, title, text) => {
images.push({
href: href,
title: title,
text: text
});
images = images;
const imageId = `${id}-${images.length}`;
const interval = setInterval(() => {
if (document.getElementById(`image-${imageId}`)) {
clearInterval(interval);
new Image({
target: document.getElementById(`image-${imageId}`),
props: {
src: href,
alt: text
},
hydrate: true
});
}
}, 10);
return `<div id="image-${id}-${images.length}" />`;
};
};
// 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)
...
@@ -30,24 +89,31 @@
...
@@ -30,24 +89,31 @@
const html = origLinkRenderer.call(renderer, href, title, text);
const html = origLinkRenderer.call(renderer, href, title, text);
return html.replace(/^<a /, '<a target="_blank" rel="nofollow" ');
return html.replace(/^<a /, '<a target="_blank" rel="nofollow" ');
};
};
const { extensions, ...defaults } = marked.getDefaults() as marked.MarkedOptions & {
const { extensions, ...defaults } = marked.getDefaults() as marked.MarkedOptions & {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
extensions: any;
extensions: any;
};
};
$: if (tokens) {
images = [];
codes = [];
}
</script>
</script>
{#each tokens as token, tokenIdx (`${id}-${tokenIdx}`)}
<div bind:this={containerElement} class="flex flex-col">
{#if token.type === 'code'}
{#each tokens as token, tokenIdx (`${id}-${tokenIdx}`)}
{#if token.lang === 'mermaid'}
{#if token.type === 'code'}
<pre class="mermaid">{revertSanitizedResponseContent(token.text)}</pre>
{#if token.lang === 'mermaid'}
{:else}
<pre class="mermaid">{revertSanitizedResponseContent(token.text)}</pre>
<CodeBlock
{:else}
id={`${id}-${tokenIdx}`}
<CodeBlock
lang={token?.lang ?? ''}
id={`${id}-${tokenIdx}`}
code={revertSanitizedResponseContent(token?.text ?? '')}
lang={token?.lang ?? ''}
/>
code={revertSanitizedResponseContent(token?.text ?? '')}
{/if}
/>
<!-- {:else if token.type === 'heading'}
{/if}
<!-- {:else if token.type === 'heading'}
<svelte:element this={headerComponent(token.depth)}>
<svelte:element this={headerComponent(token.depth)}>
<MarkdownInlineTokens id={`${id}-${tokenIdx}-h`} tokens={token.tokens} />
<MarkdownInlineTokens id={`${id}-${tokenIdx}-h`} tokens={token.tokens} />
</svelte:element>
</svelte:element>
...
@@ -119,7 +185,7 @@
...
@@ -119,7 +185,7 @@
</tbody>
</tbody>
</table>
</table>
{:else if token.type === 'text'} -->
{:else if token.type === 'text'} -->
<!-- {#if top}
<!-- {#if top}
<p>
<p>
{#if token.tokens}
{#if token.tokens}
<MarkdownInlineTokens id={`${id}-${tokenIdx}-t`} tokens={token.tokens} />
<MarkdownInlineTokens id={`${id}-${tokenIdx}-t`} tokens={token.tokens} />
...
@@ -132,12 +198,13 @@
...
@@ -132,12 +198,13 @@
{:else}
{:else}
{unescapeHtml(token.text)}
{unescapeHtml(token.text)}
{/if} -->
{/if} -->
{:else}
{:else}
{@html marked.parse(token.raw, {
{@html marked.parse(token.raw, {
...defaults,
...defaults,
gfm: true,
gfm: true,
breaks: true,
breaks: true,
renderer
renderer
})}
})}
{/if}
{/if}
{/each}
{/each}
</div>
src/lib/components/common/Image.svelte
View file @
e6b3de31
...
@@ -13,18 +13,13 @@
...
@@ -13,18 +13,13 @@
let showImagePreview = false;
let showImagePreview = false;
</script>
</script>
<div class={className}>
<button
<!-- svelte-ignore a11y-click-events-have-key-events -->
class={className}
<!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
on:click={() => {
<img
showImagePreview = true;
on:click={() => {
}}
showImagePreview = true;
>
}}
<img src={_src} {alt} class=" rounded-lg cursor-pointer" draggable="false" data-cy="image" />
src={_src}
</button>
{alt}
class=" rounded-lg cursor-pointer"
draggable="false"
data-cy="image"
/>
</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