diff --git a/legacy/core/src/main/java/com/fsck/k9/message/html/DisplayHtml.kt b/legacy/core/src/main/java/com/fsck/k9/message/html/DisplayHtml.kt index d098b20e486..f1551b3aa2d 100644 --- a/legacy/core/src/main/java/com/fsck/k9/message/html/DisplayHtml.kt +++ b/legacy/core/src/main/java/com/fsck/k9/message/html/DisplayHtml.kt @@ -1,65 +1,40 @@ package com.fsck.k9.message.html import app.k9mail.html.cleaner.HtmlHeadProvider -import org.intellij.lang.annotations.Language class DisplayHtml(private val settings: HtmlSettings) : HtmlHeadProvider { override val headHtml: String get() { - @Language("HTML") - val html = """ - - ${cssStyleGlobal()} - ${cssStylePre()} - ${cssStyleSignature()} - """.trimIndent() - - return html + return """""" + + cssStyleTheme() + + cssStylePre() + + cssStyleSignature() } fun wrapStatusMessage(status: CharSequence): String { - @Language("HTML") - val html = """ -
$status
- """.trimIndent() - - return wrapMessageContent(html) + return wrapMessageContent("
$status
") } - @Language("HTML") fun wrapMessageContent(messageContent: CharSequence): String { // Include a meta tag so the WebView will not use a fixed viewport width of 980 px - return """ - - - $headHtml - - - $messageContent - - - """.trimIndent() + return "" + + cssStyleTheme() + + cssStylePre() + + "" + + messageContent + + "" } - /** - * Dynamically generates a CSS style block that applies global rules to all elements (`*` selector). - * - * The style enforces word-breaking and overflow wrapping to prevent content overflow - * and ensures long text strings break correctly without causing horizontal scrolling. - * - * @return A ` - """.trimIndent() + private fun cssStyleTheme(): String { + return if (settings.useDarkMode) { + // TODO: Don't hardcode these values. Inject them via HtmlSettings. + " " + } else { + "" + } } /** @@ -70,30 +45,15 @@ class DisplayHtml(private val settings: HtmlSettings) : HtmlHeadProvider { * @return A ` - """.trimIndent() + return "" } - @Language("HTML") private fun cssStyleSignature(): String { - return """ - - """.trimIndent() + return """""" } } diff --git a/legacy/core/src/test/java/com/fsck/k9/message/html/DisplayHtmlTest.kt b/legacy/core/src/test/java/com/fsck/k9/message/html/DisplayHtmlTest.kt index f26b972da6a..41132e96c85 100644 --- a/legacy/core/src/test/java/com/fsck/k9/message/html/DisplayHtmlTest.kt +++ b/legacy/core/src/test/java/com/fsck/k9/message/html/DisplayHtmlTest.kt @@ -2,15 +2,13 @@ package com.fsck.k9.message.html import assertk.Assert import assertk.assertThat -import assertk.assertions.contains import assertk.assertions.hasSize import assertk.assertions.isEqualTo import org.jsoup.Jsoup import org.junit.Test class DisplayHtmlTest { - val htmlSettings = HtmlSettings(useDarkMode = false, useFixedWidthFont = false) - val displayHtml = DisplayHtml(htmlSettings) + val displayHtml = DisplayHtml(HtmlSettings(useDarkMode = false, useFixedWidthFont = false)) @Test fun wrapMessageContent_addsViewportMetaElement() { @@ -27,45 +25,19 @@ class DisplayHtmlTest { } @Test - fun wrapMessageContent_addsPreCSSStyles() { + fun wrapMessageContent_addsPreCSS() { val html = displayHtml.wrapMessageContent("Some text") - assertThat(html).containsHtmlElement("head > style", 3) - } - - @Test - fun wrapMessageContent_addsGlobalStyleRules() { - val html = displayHtml.wrapMessageContent("test") - - assertThat(html).containsStyleRulesFor( - selector = "*", - "word-break: break-word;", - "overflow-wrap: break-word;", - ) + assertThat(html).containsHtmlElement("head > style") } @Test - fun wrapMessageContent_addsPreCSS() { - val html = displayHtml.wrapMessageContent("test") - val expectedFont = if (htmlSettings.useFixedWidthFont) "monospace" else "sans-serif" - - assertThat(html).containsStyleRulesFor( - selector = "pre.${EmailTextToHtml.K9MAIL_CSS_CLASS}", - "white-space: pre-wrap;", - "word-wrap: break-word;", - "font-family: $expectedFont;", - "margin-top: 0px;", - ) - } + fun wrapMessageContent_whenDarkMessageViewTheme_addsDarkThemeCSS() { + val darkModeDisplayHtml = DisplayHtml(HtmlSettings(useDarkMode = true, useFixedWidthFont = false)) - @Test - fun wrapMessageContent_addsSignatureStyleRules() { - val html = displayHtml.wrapMessageContent("test") + val html = darkModeDisplayHtml.wrapMessageContent("Some text") - assertThat(html).containsStyleRulesFor( - selector = ".k9mail-signature", - "opacity: 0.5;", - ) + assertThat(html).htmlElements("head > style").hasSize(2) } @Test @@ -77,26 +49,8 @@ class DisplayHtmlTest { assertThat(html).bodyText().isEqualTo(content) } - private fun Assert.containsStyleRulesFor(selector: String, vararg expectedRules: String) = given { html -> - val styleContent = Jsoup.parse(html) - .select("style") - .joinToString("\n") { it.data() } - - val selectorPattern = Regex.escape(selector).replace("\\*", "\\\\*") - val selectorBlock = Regex("$selectorPattern\\s*\\{([^}]*)\\}", RegexOption.MULTILINE) - .find(styleContent) - ?.groupValues?.get(1) - ?.trim() - - requireNotNull(selectorBlock) { "No style block found for selector: $selector" } - - expectedRules.forEach { rule -> - assertThat(selectorBlock).contains(rule) - } - } - - private fun Assert.containsHtmlElement(cssQuery: String, expectedCount: Int = 1) = given { actual -> - assertThat(actual).htmlElements(cssQuery).hasSize(expectedCount) + private fun Assert.containsHtmlElement(cssQuery: String) = given { actual -> + assertThat(actual).htmlElements(cssQuery).hasSize(1) } private fun Assert.htmlElements(cssQuery: String) = transform { html ->