Render plain-text mail with its line breaks
`htmlBody` is a derived list, not a filter: RFC 8621 §4.1.4 gives a message with no HTML alternative one anyway, holding the text/plain part. Testing `Boolean(htmlRaw)` therefore answered "this is HTML" for every plain-text mail, sending it to HtmlBody and `.ihm-email-root`, which is `white-space: normal` and collapses every line break. Hard-wrapped mail arrived as a single paragraph with the signature and the quoted reply run into the prose. Confirmed live against Stalwart 0.16.21 (2026-09-10): a plain-text message comes back with `htmlBody` and `textBody` naming the same part, typed text/plain, while a real multipart/alternative names two different parts. `type` was already in BODY_PROPS; nothing looked at it. TextBody was written for exactly these messages and was simply unreachable, so this also restores what it does -- pre-wrap, quote-depth colouring and the collapsible quoted block, none of which had ever fired on plain-text mail.
This commit is contained in:
@@ -18,7 +18,7 @@ import { internalDomains, isExternalSender, linkVerdict } from "@/lib/warnings";
|
||||
import { spamReport, type SpamReport } from "@/lib/spamScore";
|
||||
import { formatFullDate, formatListDate, formatSize } from "@/lib/format";
|
||||
import { displayName, domainOf, formatAddress } from "@/lib/address";
|
||||
import { EMAIL_BASE_CSS, TEXT_EMAIL_CSS, htmlDeclaresColors, markKeptSurfaces, sanitizeEmailHtml } from "@/lib/html";
|
||||
import { EMAIL_BASE_CSS, TEXT_EMAIL_CSS, hasHtmlAlternative, htmlDeclaresColors, markKeptSurfaces, sanitizeEmailHtml } from "@/lib/html";
|
||||
import { openableInTab, previewKind } from "@/lib/preview";
|
||||
import { FilePreviewDialog } from "@/ui/filepreview";
|
||||
import { findQuoteStart, htmlToText, textToHtml } from "@/lib/text";
|
||||
@@ -137,7 +137,9 @@ export const MessageView = memo(function MessageView({ email: e, expanded, wasUn
|
||||
const textPart = e.textBody?.[0];
|
||||
const htmlRaw = htmlPart?.partId ? e.bodyValues?.[htmlPart.partId]?.value : undefined;
|
||||
const textRaw = textPart?.partId ? e.bodyValues?.[textPart.partId]?.value : undefined;
|
||||
const showHtml = Boolean(htmlRaw);
|
||||
// Not `Boolean(htmlRaw)`: `htmlBody` carries the text part when there is no
|
||||
// HTML alternative. See hasHtmlAlternative().
|
||||
const showHtml = hasHtmlAlternative(htmlPart, htmlRaw);
|
||||
const themeMessageBody = settings.themeMessageBody;
|
||||
const themeStyledMessages = settings.themeStyledMessages;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user