mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-11-02 03:06:14 +00:00
Fall back to the message body when the formatted body has nothing to render
The HTML sanitiser in toHtmlDocument() drops every tag outside its safelist, which does not include img. A formatted body whose only content is an image — a custom emoji, or a bot posting an image inline — therefore cleans down to an empty document, and because that document is not null the ?: body fallbacks in the timeline item factory, the room list preview, the notification resolver and plainText are all dead. The message renders as an empty bubble. Return null from toHtmlDocument() when no text survives the sanitisation, so the existing fallbacks take the plain text body, which for these messages carries the alt text the sender provided.
This commit is contained in:
+19
@@ -229,6 +229,25 @@ class TimelineItemContentMessageFactoryTest : RobolectricTest() {
|
||||
assertThat((result as TimelineItemTextContent).formattedBody).isEqualTo(SpannedString("body"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test create TextMessageType with a formatted body containing only an image falls back to the body`() = runTest {
|
||||
val sut = createTimelineItemContentMessageFactory()
|
||||
val result = sut.create(
|
||||
content = createMessageContent(
|
||||
type = TextMessageType(
|
||||
body = "\uD83D\uDE1C",
|
||||
formatted = FormattedBody(MessageFormat.HTML, "<img src=\"mxc://matrix.org/anImage\" alt=\"\uD83D\uDE1C\" />")
|
||||
)
|
||||
),
|
||||
senderId = A_USER_ID,
|
||||
senderProfile = aProfileDetails(),
|
||||
eventId = AN_EVENT_ID,
|
||||
)
|
||||
assertThat((result as TimelineItemTextContent).formattedBody).isEqualTo(SpannedString("\uD83D\uDE1C"))
|
||||
assertThat(result.htmlDocument).isNull()
|
||||
assertThat(result.plainText).isEqualTo("\uD83D\uDE1C")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test create VideoMessageType`() = runTest {
|
||||
val sut = createTimelineItemContentMessageFactory()
|
||||
|
||||
+3
-2
@@ -19,7 +19,8 @@ import org.jsoup.safety.Safelist
|
||||
|
||||
/**
|
||||
* Converts the HTML string [FormattedBody.body] to a [Document] by parsing it.
|
||||
* If the message is not formatted or the format is not [MessageFormat.HTML] we return `null`.
|
||||
* If the message is not formatted, the format is not [MessageFormat.HTML], or nothing renderable is left once the
|
||||
* unsupported tags have been removed, we return `null` so that the plain text body is used instead.
|
||||
*
|
||||
* This will also make sure mentions are prefixed with `@`.
|
||||
*
|
||||
@@ -44,7 +45,7 @@ fun FormattedBody.toHtmlDocument(
|
||||
// Prepend `@` to mentions
|
||||
fixMentions(dom, permalinkParser)
|
||||
|
||||
dom
|
||||
dom.takeIf { it.text().isNotBlank() }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+24
@@ -103,4 +103,28 @@ class ToHtmlDocumentTest : RobolectricTest() {
|
||||
})
|
||||
assertThat(document?.text()).isEqualTo("Hey Alice!")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `toHtmlDocument - returns null if the body only contains unsupported tags`() {
|
||||
val body = FormattedBody(
|
||||
format = MessageFormat.HTML,
|
||||
body = "<img data-mx-emoticon src=\"mxc://matrix.org/anImage\" height=\"32\" width=\"32\" alt=\"\uD83D\uDE1C\" />"
|
||||
)
|
||||
|
||||
val document = body.toHtmlDocument(permalinkParser = FakePermalinkParser())
|
||||
|
||||
assertThat(document).isNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `toHtmlDocument - returns a Document if some text survives next to unsupported tags`() {
|
||||
val body = FormattedBody(
|
||||
format = MessageFormat.HTML,
|
||||
body = "Look at this <img src=\"mxc://matrix.org/anImage\" alt=\"cat\" />!"
|
||||
)
|
||||
|
||||
val document = body.toHtmlDocument(permalinkParser = FakePermalinkParser())
|
||||
|
||||
assertThat(document?.text()).isEqualTo("Look at this !")
|
||||
}
|
||||
}
|
||||
|
||||
+12
@@ -149,4 +149,16 @@ class ToPlainTextTest : RobolectricTest() {
|
||||
)
|
||||
assertThat(messageType.toPlainText(permalinkParser = FakePermalinkParser())).isEqualTo("This is the message content.")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `TextMessageType toPlainText - returns the body if the formatted one only contains an image`() {
|
||||
val messageType = TextMessageType(
|
||||
body = "\uD83D\uDE1C",
|
||||
formatted = FormattedBody(
|
||||
format = MessageFormat.HTML,
|
||||
body = "<img data-mx-emoticon src=\"mxc://matrix.org/anImage\" height=\"32\" width=\"32\" alt=\"\uD83D\uDE1C\" />"
|
||||
)
|
||||
)
|
||||
assertThat(messageType.toPlainText(permalinkParser = FakePermalinkParser())).isEqualTo("\uD83D\uDE1C")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user