Remove legacy mx-reply from toPlainText formatted event contents (#6683)
This commit is contained in:
parent
1eeabb1e64
commit
d215354e64
3 changed files with 57 additions and 3 deletions
|
|
@ -12,8 +12,10 @@ import io.element.android.libraries.matrix.api.permalink.PermalinkData
|
|||
import io.element.android.libraries.matrix.api.permalink.PermalinkParser
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.FormattedBody
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.MessageFormat
|
||||
import io.element.android.wysiwyg.utils.HtmlToDomParser
|
||||
import org.jsoup.Jsoup
|
||||
import org.jsoup.nodes.Document
|
||||
import org.jsoup.nodes.Document.OutputSettings
|
||||
import org.jsoup.safety.Safelist
|
||||
|
||||
/**
|
||||
* Converts the HTML string [FormattedBody.body] to a [Document] by parsing it.
|
||||
|
|
@ -34,9 +36,9 @@ fun FormattedBody.toHtmlDocument(
|
|||
?.trimEnd()
|
||||
?.let { formattedBody ->
|
||||
val dom = if (prefix != null) {
|
||||
HtmlToDomParser.document("$prefix $formattedBody")
|
||||
CustomHtmlToDomParser.document("$prefix $formattedBody")
|
||||
} else {
|
||||
HtmlToDomParser.document(formattedBody)
|
||||
CustomHtmlToDomParser.document(formattedBody)
|
||||
}
|
||||
|
||||
// Prepend `@` to mentions
|
||||
|
|
@ -60,3 +62,35 @@ private fun fixMentions(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Custom Html to DOM parser, based on the one included in the rich text editor library. */
|
||||
private object CustomHtmlToDomParser {
|
||||
fun document(html: String): Document {
|
||||
val outputSettings = OutputSettings().prettyPrint(false).indentAmount(0)
|
||||
val cleanHtml = Jsoup.clean(html, "", safeList, outputSettings)
|
||||
return Jsoup.parse(cleanHtml)
|
||||
}
|
||||
|
||||
private val safeList = Safelist()
|
||||
.addTags(
|
||||
"a",
|
||||
"b",
|
||||
"strong",
|
||||
"i",
|
||||
"em",
|
||||
"u",
|
||||
"del",
|
||||
"code",
|
||||
"ul",
|
||||
"ol",
|
||||
"li",
|
||||
"pre",
|
||||
"blockquote",
|
||||
"p",
|
||||
"br",
|
||||
// Add custom `mx-reply` tag, even if it's just to remove its contents from the plain text version of the message
|
||||
"mx-reply"
|
||||
)
|
||||
.addAttributes("a", "href", "data-mention-type", "contenteditable")
|
||||
.addAttributes("ol", "start")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,6 +65,8 @@ fun Document.toPlainText(): String {
|
|||
return visitor.build()
|
||||
}
|
||||
|
||||
private const val FALLBACK_REPLY_NODE_TAG = "mx-reply"
|
||||
|
||||
private class PlainTextNodeVisitor : NodeVisitor {
|
||||
private val builder = StringBuilder()
|
||||
|
||||
|
|
@ -92,6 +94,9 @@ private class PlainTextNodeVisitor : NodeVisitor {
|
|||
} else {
|
||||
builder.append("• ")
|
||||
}
|
||||
} else if (node is Element && node.tagName() == FALLBACK_REPLY_NODE_TAG) {
|
||||
// Remove the fallback reply node and its contents so they aren't added to the plain text message
|
||||
node.remove()
|
||||
} else if (node is Element && node.isBlock && builder.lastOrNull() != '\n') {
|
||||
builder.append("\n")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -136,4 +136,19 @@ class ToPlainTextTest {
|
|||
)
|
||||
assertThat(messageType.toPlainText(permalinkParser = FakePermalinkParser())).isEqualTo("This is the fallback text")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `TextMessageType toPlainText - ignores mx-reply element`() {
|
||||
val messageType = TextMessageType(
|
||||
body = "This is the fallback text",
|
||||
formatted = FormattedBody(
|
||||
format = MessageFormat.HTML,
|
||||
body = """
|
||||
<mx-reply>In reply to...</mx-reply>
|
||||
This is the message content.
|
||||
""".trimIndent()
|
||||
)
|
||||
)
|
||||
assertThat(messageType.toPlainText(permalinkParser = FakePermalinkParser())).isEqualTo("This is the message content.")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue