MarkdownInlineTokens.svelte 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. <script lang="ts">
  2. import DOMPurify from 'dompurify';
  3. import type { Token } from 'marked';
  4. import { revertSanitizedResponseContent, unescapeHtml } from '$lib/utils';
  5. import { onMount } from 'svelte';
  6. import Image from '$lib/components/common/Image.svelte';
  7. import KatexRenderer from './KatexRenderer.svelte';
  8. import { WEBUI_BASE_URL } from '$lib/constants';
  9. export let id: string;
  10. export let tokens: Token[];
  11. </script>
  12. {#each tokens as token}
  13. {#if token.type === 'escape'}
  14. {unescapeHtml(token.text)}
  15. {:else if token.type === 'html'}
  16. {@const html = DOMPurify.sanitize(token.text)}
  17. {#if html && html.includes('<video')}
  18. {@html html}
  19. {:else if token.text.includes(`<iframe src="${WEBUI_BASE_URL}/api/v1/files/`)}
  20. {@html `${token.text}`}
  21. {:else}
  22. {token.text}
  23. {/if}
  24. {:else if token.type === 'link'}
  25. <a href={token.href} target="_blank" rel="nofollow" title={token.title}>{token.text}</a>
  26. {:else if token.type === 'image'}
  27. <Image src={token.href} alt={token.text} />
  28. {:else if token.type === 'strong'}
  29. <strong>
  30. <svelte:self id={`${id}-strong`} tokens={token.tokens} />
  31. </strong>
  32. {:else if token.type === 'em'}
  33. <em>
  34. <svelte:self id={`${id}-em`} tokens={token.tokens} />
  35. </em>
  36. {:else if token.type === 'codespan'}
  37. <code class="codespan">{unescapeHtml(token.text)}</code>
  38. {:else if token.type === 'br'}
  39. <br />
  40. {:else if token.type === 'del'}
  41. <del>
  42. <svelte:self id={`${id}-del`} tokens={token.tokens} />
  43. </del>
  44. {:else if token.type === 'inlineKatex'}
  45. {#if token.text}
  46. <KatexRenderer content={revertSanitizedResponseContent(token.text)} displayMode={false} />
  47. {/if}
  48. {:else if token.type === 'iframe'}
  49. <iframe
  50. src="{WEBUI_BASE_URL}/api/v1/files/{token.fileId}/content"
  51. title={token.fileId}
  52. width="100%"
  53. frameborder="0"
  54. onload="this.style.height=(this.contentWindow.document.body.scrollHeight+20)+'px';"
  55. ></iframe>
  56. {:else if token.type === 'text'}
  57. {token.raw}
  58. {/if}
  59. {/each}