Repository: thunderbird/thunderbird-android (language: kotlin)

Issue:
broken display of
### Checklist

- [X] I have used the search function to see if someone else has already submitted the same bug report.
- [X] I will describe the problem with as much detail as possible.

### App version

5.9.10

### Where did you get the app from?

Other

### Android version

Android 11, Havoc OS (custom)

### Device model

OnePlus 3T

### Steps to reproduce

Open mail by Mozilla

### Expected behavior

continous layout without gaps.

### Actual behavior

There is lots of blank space between paragraphs. (several times the device height between each paragraph is just white screen space so you need to scroll very far)
This might be due to the nested table layout but without a debugger it's hard for me to figure out which html tags K9 might have removed that broke the layout this way.

If you have time at some point, then please take a look.
No high priority, I just noticed the broken layout.

I attached the email as an html file. I modified three a href attributes, the rest is unmodified.
[mail.html zipped](https://github.com/k9mail/k-9/files/7936679/mail.zip)

### Logs

_No response_


Discussion hints:
I created a command line application that modifies HTML the same way that K-9 Mail does. See #5885

Could you use this to debug the issue yourself?
yes,
I finally had the time to look at this.

I tested this in Firefox and used the inspection tools in order to switch to a mobile layout (smartphone icon on the right)

The html mail starts with 
```
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">
<head>
    <!--[if gte mso 9]>
    <xml>
        <o:OfficeDocumentSettings>
            <o:AllowPNG/>
            <o:PixelsPerInch>96</o:PixelsPerInch>
        </o:OfficeDocumentSettings>
    </xml>
    <![endif]-->
```

Your scripts removes everything but keeps the naked html and head tags.
The actually relevant part of the code above seems to be the doctype.
Reintroducing it (html 4 strict)
`<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">`
or the html5 doctype instead:
`<!doctype html>`
both lines fix the layout.

The issue being:
The layout uses divs (one attribute only: height:100%) for nesting.
According to [Stackoverlow](https://stackoverflow.com/questions/1997842/why-certain-doctype-declarations-cause-100-height-tables-and-divs-to-stop-worki):
> If you have height: 100% and the height of the parent element is auto then [100% means auto](http://www.w3.org/TR/CSS21/visudet.html#the-height-property).

the new strict behavior in browser engines interpret the height differently and lets the element inherit from it's parent.
Removing the doctype makes the engine go into "quirks" mode and interprets the layout/css differently. (legacy mode)
Quirks mode then actually renders this height: 100% which in turn creates lots of blank space between each element of the layout.

I don't know why these nested divs (parent element: grid-div; child element: table) even exist in the first place (maybe legacy mail clients?), but removing them instead of the !doctype also fixes the layout.

But you might want to think about keeping !doctypes intact unless this was done to prevent other mail layouts from breaking

Pull request: Retain doctype when sanitizing HTML
Fixes #5882

Test command: ./gradlew :app:html-cleaner:test --tests "app.k9mail.html.cleaner.HtmlSanitizerTest"

Fix patch:
diff --git a/app/html-cleaner/src/main/java/app/k9mail/html/cleaner/BodyCleaner.kt b/app/html-cleaner/src/main/java/app/k9mail/html/cleaner/BodyCleaner.kt
index 70045fe60bf..0720118d385 100644
--- a/app/html-cleaner/src/main/java/app/k9mail/html/cleaner/BodyCleaner.kt
+++ b/app/html-cleaner/src/main/java/app/k9mail/html/cleaner/BodyCleaner.kt
@@ -43,10 +43,17 @@ internal class BodyCleaner {
 
     fun clean(dirtyDocument: Document): Document {
         val cleanedDocument = cleaner.clean(dirtyDocument)
+        copyDocumentType(dirtyDocument, cleanedDocument)
         copyBodyAttributes(dirtyDocument, cleanedDocument)
         return cleanedDocument
     }
 
+    private fun copyDocumentType(dirtyDocument: Document, cleanedDocument: Document) {
+        dirtyDocument.documentType()?.let { documentType ->
+            cleanedDocument.insertChildren(0, documentType)
+        }
+    }
+
     private fun copyBodyAttributes(dirtyDocument: Document, cleanedDocument: Document) {
         val cleanedBody = cleanedDocument.body()
         for (attribute in dirtyDocument.body().attributes()) {


Test patch:
diff --git a/app/html-cleaner/src/test/java/app/k9mail/html/cleaner/HtmlSanitizerTest.kt b/app/html-cleaner/src/test/java/app/k9mail/html/cleaner/HtmlSanitizerTest.kt
index 7630fd56271..9ebc3857b5e 100644
--- a/app/html-cleaner/src/test/java/app/k9mail/html/cleaner/HtmlSanitizerTest.kt
+++ b/app/html-cleaner/src/test/java/app/k9mail/html/cleaner/HtmlSanitizerTest.kt
@@ -376,6 +376,37 @@ class HtmlSanitizerTest {
         )
     }
 
+    @Test
+    fun `should keep HTML 5 doctype`() {
+        val html =
+            """
+            <!doctype html>
+            <html><head></head><body>text</body></html>
+            """.trimIndent().trimLineBreaks()
+
+        val result = htmlSanitizer.sanitize(html)
+
+        assertThat(result.toCompactString()).isEqualTo(html)
+    }
+
+    @Test
+    fun `should keep HTML 4_01 doctype`() {
+        val html =
+            """
+            <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+            <html><head></head><body>text</body></html>
+            """.trimIndent().trimLineBreaks()
+
+        val result = htmlSanitizer.sanitize(html)
+
+        assertThat(result.toCompactString()).isEqualTo(
+            """
+            <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+            <html><head></head><body>text</body></html>
+            """.trimIndent().trimLineBreaks()
+        )
+    }
+
     private fun Document.toCompactString(): String {
         outputSettings()
             .prettyPrint(false)