When linkifying, adjust the URLSpan's url too (#6188)
This commit is contained in:
parent
b6be7e051c
commit
33a78ecda3
2 changed files with 29 additions and 5 deletions
|
|
@ -16,8 +16,6 @@ import androidx.core.text.toSpannable
|
||||||
import androidx.core.text.util.LinkifyCompat
|
import androidx.core.text.util.LinkifyCompat
|
||||||
import io.element.android.libraries.core.extensions.runCatchingExceptions
|
import io.element.android.libraries.core.extensions.runCatchingExceptions
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import kotlin.collections.component1
|
|
||||||
import kotlin.collections.component2
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper class to linkify text while preserving existing URL spans.
|
* Helper class to linkify text while preserving existing URL spans.
|
||||||
|
|
@ -59,7 +57,8 @@ object LinkifyHelper {
|
||||||
|
|
||||||
// Adapt the url in the URL span to the new end index too if needed
|
// Adapt the url in the URL span to the new end index too if needed
|
||||||
if (end != newEnd) {
|
if (end != newEnd) {
|
||||||
val url = spannable.subSequence(start, newEnd).toString()
|
val diff = end - newEnd
|
||||||
|
val url = urlSpan.url.substring(0, urlSpan.url.length - diff)
|
||||||
spannable.removeSpan(urlSpan)
|
spannable.removeSpan(urlSpan)
|
||||||
spannable.setSpan(URLSpan(url), start, newEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
spannable.setSpan(URLSpan(url), start, newEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -87,12 +86,12 @@ object LinkifyHelper {
|
||||||
var end = end
|
var end = end
|
||||||
|
|
||||||
// Trailing punctuation found, adjust the end index
|
// Trailing punctuation found, adjust the end index
|
||||||
while (spannable[end - 1] in sequenceOf('.', ',', ';', ':', '!', '?', '…') && end > start) {
|
while (end > start && spannable[end - 1] in sequenceOf('.', ',', ';', ':', '!', '?', '…')) {
|
||||||
end--
|
end--
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the last character is a closing parenthesis, check if it's part of a pair
|
// If the last character is a closing parenthesis, check if it's part of a pair
|
||||||
if (spannable[end - 1] == ')' && end > start) {
|
if (end > start && spannable[end - 1] == ')') {
|
||||||
val linkifiedTextLastPath = spannable.substring(start, end).substringAfterLast('/')
|
val linkifiedTextLastPath = spannable.substring(start, end).substringAfterLast('/')
|
||||||
val closingParenthesisCount = linkifiedTextLastPath.count { it == ')' }
|
val closingParenthesisCount = linkifiedTextLastPath.count { it == ')' }
|
||||||
val openingParenthesisCount = linkifiedTextLastPath.count { it == '(' }
|
val openingParenthesisCount = linkifiedTextLastPath.count { it == '(' }
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,9 @@ package io.element.android.libraries.androidutils.text
|
||||||
|
|
||||||
import android.telephony.TelephonyManager
|
import android.telephony.TelephonyManager
|
||||||
import android.text.style.URLSpan
|
import android.text.style.URLSpan
|
||||||
|
import androidx.core.text.buildSpannedString
|
||||||
import androidx.core.text.getSpans
|
import androidx.core.text.getSpans
|
||||||
|
import androidx.core.text.inSpans
|
||||||
import androidx.core.text.toSpannable
|
import androidx.core.text.toSpannable
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import io.element.android.tests.testutils.WarmUpRule
|
import io.element.android.tests.testutils.WarmUpRule
|
||||||
|
|
@ -140,4 +142,27 @@ class LinkifierHelperTest {
|
||||||
assertThat(urlSpans.size).isEqualTo(1)
|
assertThat(urlSpans.size).isEqualTo(1)
|
||||||
assertThat(urlSpans.first().url).isEqualTo("https://github.com/element-hq/element-android/READ(ME)")
|
assertThat(urlSpans.first().url).isEqualTo("https://github.com/element-hq/element-android/READ(ME)")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `linkification handles trailing question marks`() {
|
||||||
|
val text = "A url: https://github.com/element-hq/element-android?"
|
||||||
|
val result = LinkifyHelper.linkify(text)
|
||||||
|
val urlSpans = result.toSpannable().getSpans<URLSpan>()
|
||||||
|
assertThat(urlSpans.size).isEqualTo(1)
|
||||||
|
assertThat(urlSpans.first().url).isEqualTo("https://github.com/element-hq/element-android")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `linkification doesn't modify existing URLSpan`() {
|
||||||
|
val text = buildSpannedString {
|
||||||
|
append("A url: ")
|
||||||
|
inSpans(URLSpan("https://github.com/element-hq/element-android?")) {
|
||||||
|
append("here")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val result = LinkifyHelper.linkify(text)
|
||||||
|
val urlSpans = result.toSpannable().getSpans<URLSpan>()
|
||||||
|
assertThat(urlSpans.size).isEqualTo(1)
|
||||||
|
assertThat(urlSpans.first().url).isEqualTo("https://github.com/element-hq/element-android?")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue