Merge branch 'develop' into fix/2614-linkify-ipv6-urls

This commit is contained in:
Benoit Marty
2026-08-12 13:48:36 +02:00
committed by GitHub
739 changed files with 6362 additions and 3368 deletions
@@ -50,6 +50,11 @@ object LinkifyHelper {
val start = spannable.getSpanStart(urlSpan)
val end = spannable.getSpanEnd(urlSpan)
if (urlSpan !in oldURLSpans && spannable.isEmailInsideFediverseHandle(urlSpan, start)) {
spannable.removeSpan(urlSpan)
continue
}
// Try to avoid including trailing punctuation in the link.
// Since this might fail in some edge cases, we catch the exception and just use the original end index.
val newEnd = runCatchingExceptions {
@@ -108,6 +113,10 @@ object LinkifyHelper {
return host.startsWith('[') && host.endsWith(']')
}
private fun Spannable.isEmailInsideFediverseHandle(urlSpan: URLSpan, start: Int): Boolean {
return urlSpan.url.startsWith("mailto:") && start > 0 && this[start - 1] == '@'
}
private fun adjustLinkifiedUrlSpanEndIndex(spannable: Spannable, start: Int, end: Int): Int {
var end = end
@@ -13,3 +13,5 @@ import java.nio.charset.Charset
fun String.urlEncoded(charset: Charset = Charsets.UTF_8): String = URLEncoder.encode(this, charset.name())
fun String.urlDecoded(charset: Charset = Charsets.UTF_8): String = URLDecoder.decode(this, charset.name())
fun String.takeIfNotBlank(): String? = ifBlank { null }
@@ -141,6 +141,45 @@ class LinkifierHelperTest : RobolectricTest() {
assertThat(urlSpans.first().url).isEqualTo("tel:1234")
}
@Test
fun `linkification ignores fediverse handle`() {
val text = "Follow me at @name@server.tld"
val result = LinkifyHelper.linkify(text)
val urlSpans = result.toSpannable().getSpans<URLSpan>()
assertThat(urlSpans).isEmpty()
}
@Test
fun `linkification ignores fediverse handle at the start of the text`() {
val text = "@name@server.tld posted this"
val result = LinkifyHelper.linkify(text)
val urlSpans = result.toSpannable().getSpans<URLSpan>()
assertThat(urlSpans).isEmpty()
}
@Test
fun `linkification finds email next to a fediverse handle`() {
val text = "@name@server.tld and john@doe.com"
val result = LinkifyHelper.linkify(text)
val urlSpans = result.toSpannable().getSpans<URLSpan>()
assertThat(urlSpans.size).isEqualTo(1)
assertThat(urlSpans.first().url).isEqualTo("mailto:john@doe.com")
}
@Test
fun `linkification keeps an existing mailto span preceded by an at sign`() {
val text = buildSpannedString {
append("Mail me @")
inSpans(URLSpan("mailto:john@doe.com")) {
append("john@doe.com")
}
}
val result = LinkifyHelper.linkify(text)
val urlSpans = result.toSpannable().getSpans<URLSpan>()
assertThat(urlSpans.size).isEqualTo(1)
assertThat(urlSpans.first().url).isEqualTo("mailto:john@doe.com")
}
@Test
fun `linkification handles trailing dot`() {
val text = "A url https://matrix.org."