97 lines
2.1 KiB
Vue
97 lines
2.1 KiB
Vue
<script setup lang="ts">
|
|
import { ref, computed, watch } from 'vue'
|
|
import type { MessageObject } from '@MailManager/models'
|
|
import { EmailSanitizer, SecurityLevel } from '@/utile/emailSanitizer'
|
|
|
|
interface Props {
|
|
message: MessageObject
|
|
securityLevel: SecurityLevel
|
|
allowImages: boolean
|
|
}
|
|
|
|
const props = defineProps<Props>()
|
|
|
|
// Computed
|
|
const displayFrame = ref<HTMLIFrameElement | null>(null)
|
|
|
|
const isHtml = computed(() => {
|
|
return props.message.hasHtmlContent()
|
|
})
|
|
|
|
const messageBody = computed(() => {
|
|
if (!props.message.hasContent()) return ''
|
|
|
|
if (props.message.hasHtmlContent()) {
|
|
return props.message.getHtmlContent() ?? ''
|
|
}
|
|
|
|
return props.message.getTextContent() ?? ''
|
|
})
|
|
|
|
const sanitizedMessageBody = computed(() => {
|
|
if (!messageBody.value || !isHtml.value) return messageBody.value
|
|
|
|
return EmailSanitizer.sanitize(messageBody.value, {
|
|
securityLevel: props.securityLevel,
|
|
allowImages: props.allowImages,
|
|
allowExternalLinks: true,
|
|
allowStyles: true
|
|
})
|
|
})
|
|
|
|
// Watchers
|
|
watch(messageBody, () => {
|
|
setTimeout(resizeIframe, 100)
|
|
})
|
|
|
|
watch(() => props.allowImages, () => {
|
|
setTimeout(resizeIframe, 100)
|
|
})
|
|
|
|
// Functions
|
|
const resizeIframe = () => {
|
|
if (displayFrame.value?.contentWindow?.document?.body) {
|
|
const height = displayFrame.value.contentWindow.document.body.scrollHeight
|
|
displayFrame.value.style.height = `${height + 20}px`
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="message-body pa-6">
|
|
<!-- HTML body (sandboxed iframe) -->
|
|
<iframe
|
|
v-if="isHtml"
|
|
ref="displayFrame"
|
|
sandbox="allow-same-origin"
|
|
class="html-content-frame"
|
|
:srcdoc="sanitizedMessageBody"
|
|
@load="resizeIframe"
|
|
/>
|
|
|
|
<!-- Plain text body -->
|
|
<pre v-else class="text-body-1 text-pre-wrap">{{ messageBody }}</pre>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped lang="scss">
|
|
.message-body {
|
|
background-color: rgb(var(--v-theme-background));
|
|
min-height: 100%;
|
|
}
|
|
|
|
.html-content-frame {
|
|
width: 100%;
|
|
border: none;
|
|
min-height: 400px;
|
|
display: block;
|
|
background: white;
|
|
}
|
|
|
|
.text-pre-wrap {
|
|
white-space: pre-wrap;
|
|
word-wrap: break-word;
|
|
font-family: inherit;
|
|
}
|
|
</style>
|