Remove legacy mx-reply from toPlainText formatted event contents (#6683)
This commit is contained in:
parent
b63c6eaba2
commit
8d7cc14096
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.permalink.PermalinkParser
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.FormattedBody
|
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.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
|
||||||
|
import org.jsoup.nodes.Document.OutputSettings
|
||||||
|
import org.jsoup.safety.Safelist
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts the HTML string [FormattedBody.body] to a [Document] by parsing it.
|
* Converts the HTML string [FormattedBody.body] to a [Document] by parsing it.
|
||||||
|
|
@ -34,9 +36,9 @@ fun FormattedBody.toHtmlDocument(
|
||||||
?.trimEnd()
|
?.trimEnd()
|
||||||
?.let { formattedBody ->
|
?.let { formattedBody ->
|
||||||
val dom = if (prefix != null) {
|
val dom = if (prefix != null) {
|
||||||
HtmlToDomParser.document("$prefix $formattedBody")
|
CustomHtmlToDomParser.document("$prefix $formattedBody")
|
||||||
} else {
|
} else {
|
||||||
HtmlToDomParser.document(formattedBody)
|
CustomHtmlToDomParser.document(formattedBody)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepend `@` to mentions
|
// 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()
|
return visitor.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private const val FALLBACK_REPLY_NODE_TAG = "mx-reply"
|
||||||
|
|
||||||
private class PlainTextNodeVisitor : NodeVisitor {
|
private class PlainTextNodeVisitor : NodeVisitor {
|
||||||
private val builder = StringBuilder()
|
private val builder = StringBuilder()
|
||||||
|
|
||||||
|
|
@ -92,6 +94,9 @@ private class PlainTextNodeVisitor : NodeVisitor {
|
||||||
} else {
|
} else {
|
||||||
builder.append("• ")
|
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') {
|
} else if (node is Element && node.isBlock && builder.lastOrNull() != '\n') {
|
||||||
builder.append("\n")
|
builder.append("\n")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -136,4 +136,19 @@ class ToPlainTextTest {
|
||||||
)
|
)
|
||||||
assertThat(messageType.toPlainText(permalinkParser = FakePermalinkParser())).isEqualTo("This is the fallback text")
|
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