Skip to content
This repository has been archived by the owner on Sep 27, 2024. It is now read-only.

Commit

Permalink
Merge pull request #1019 from matrix-org/android/use-jsoup-for-html-p…
Browse files Browse the repository at this point in the history
…arsing-fixes-line-breaks

Use Jsoup instead of TagSoup for HTML parsing.
  • Loading branch information
jmartinesp authored Jul 17, 2024
2 parents f407db4 + 5cfb891 commit 6f982ac
Show file tree
Hide file tree
Showing 8 changed files with 296 additions and 452 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ class MainActivity : ComponentActivity() {
var linkDialogAction by remember { mutableStateOf<LinkAction?>(null) }
val coroutineScope = rememberCoroutineScope()

LaunchedEffect(state.messageHtml) {
Timber.d("Message HTML: '${state.messageHtml}'")
}
val htmlText = htmlConverter.fromHtmlToSpans(state.messageHtml)

linkDialogAction?.let { linkAction ->
Expand Down
2 changes: 1 addition & 1 deletion platforms/android/gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ google-material = { module="com.google.android.material:material", version.ref="

# Misc
timber = { module="com.jakewharton.timber:timber", version.ref="timber" }
tagsoup = { module="org.ccil.cowan.tagsoup:tagsoup", version.ref="tagsoup" }
jsoup = "org.jsoup:jsoup:1.18.1"
molecule-runtime = { module = "app.cash.molecule:molecule-runtime", version.ref = "molecule" }

# Test
Expand Down
4 changes: 2 additions & 2 deletions platforms/android/library/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,8 @@ dependencies {

implementation libs.timber

// XML Parsing
api libs.tagsoup
// HTML Parsing
api libs.jsoup

implementation libs.androidx.core
implementation libs.androidx.appcompat
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ class InterceptInputConnectionIntegrationTest {
private val viewModel = EditorViewModel(
provideComposer = { newComposerModel() },
).also {
it.htmlConverter = HtmlConverter.Factory.create(context = app,
it.htmlConverter = HtmlConverter.Factory.create(
context = app,
styleConfig = styleConfig,
mentionDisplayHandler = null,
)
Expand Down Expand Up @@ -57,7 +58,7 @@ class InterceptInputConnectionIntegrationTest {
textView.text.dumpSpans(), equalTo(
listOf(
"hello: android.widget.TextView.ChangeWatcher (0-5) fl=#6553618",
"hello: android.text.style.StyleSpan (0-5) fl=#33",
"hello: android.text.style.StyleSpan (0-5) fl=#17",
"hello: android.text.method.TextKeyListener (0-5) fl=#18",
"hello: android.text.style.UnderlineSpan (0-5) fl=#289",
"hello: android.view.inputmethod.ComposingText (0-5) fl=#289",
Expand All @@ -80,7 +81,7 @@ class InterceptInputConnectionIntegrationTest {
assertThat(
textView.text.dumpSpans(), equalTo(
baseEditedSpans.toMutableList().apply {
add(1, "world: android.text.style.StyleSpan (0-5) fl=#33")
add(1, "world: android.text.style.StyleSpan (0-5) fl=#17")
}
)
)
Expand All @@ -97,7 +98,7 @@ class InterceptInputConnectionIntegrationTest {
assertThat(
textView.text.dumpSpans(), equalTo(
baseEditedSpans.toMutableList().apply {
add(1, "world: android.text.style.UnderlineSpan (0-5) fl=#33")
add(1, "world: android.text.style.UnderlineSpan (0-5) fl=#17")
}
)
)
Expand All @@ -114,7 +115,7 @@ class InterceptInputConnectionIntegrationTest {
assertThat(
textView.text.dumpSpans(), equalTo(
baseEditedSpans.toMutableList().apply {
add(1, "world: android.text.style.StrikethroughSpan (0-5) fl=#33")
add(1, "world: android.text.style.StrikethroughSpan (0-5) fl=#17")
}
)
)
Expand All @@ -131,7 +132,7 @@ class InterceptInputConnectionIntegrationTest {
assertThat(
textView.text.dumpSpans(), equalTo(
baseEditedSpans.toMutableList().apply {
add(1, "world: io.element.android.wysiwyg.view.spans.InlineCodeSpan (0-5) fl=#33")
add(1, "world: io.element.android.wysiwyg.view.spans.InlineCodeSpan (0-5) fl=#17")
}
)
)
Expand All @@ -147,7 +148,7 @@ class InterceptInputConnectionIntegrationTest {
textView.text.dumpSpans(), equalTo(
listOf(
"hello: android.widget.TextView.ChangeWatcher (0-5) fl=#6553618",
"hello: io.element.android.wysiwyg.view.spans.OrderedListSpan (0-5) fl=#34",
"hello: io.element.android.wysiwyg.view.spans.OrderedListSpan (0-5) fl=#17",
"hello: android.text.style.UnderlineSpan (0-5) fl=#289",
"hello: android.view.inputmethod.ComposingText (0-5) fl=#289",
"hello: android.text.method.TextKeyListener (0-5) fl=#18",
Expand All @@ -173,7 +174,7 @@ class InterceptInputConnectionIntegrationTest {
textView.text.dumpSpans().joinToString(",\n"), equalTo(
"""
hello: android.widget.TextView.ChangeWatcher (0-5) fl=#6553618,
hello: io.element.android.wysiwyg.view.spans.UnorderedListSpan (0-5) fl=#34,
hello: io.element.android.wysiwyg.view.spans.UnorderedListSpan (0-5) fl=#17,
hello: android.text.style.UnderlineSpan (0-5) fl=#289,
hello: android.view.inputmethod.ComposingText (0-5) fl=#289,
hello: android.text.method.TextKeyListener (0-5) fl=#18,
Expand All @@ -195,7 +196,7 @@ class InterceptInputConnectionIntegrationTest {
textView.text.dumpSpans().joinToString(",\n"), equalTo(
"""
hello: android.widget.TextView.ChangeWatcher (0-5) fl=#6553618,
hello: io.element.android.wysiwyg.view.spans.UnorderedListSpan (0-5) fl=#34,
hello: io.element.android.wysiwyg.view.spans.UnorderedListSpan (0-5) fl=#17,
hello: android.text.style.UnderlineSpan (0-5) fl=#289,
hello: android.view.inputmethod.ComposingText (0-5) fl=#289,
hello: android.text.method.TextKeyListener (0-5) fl=#18,
Expand All @@ -221,7 +222,7 @@ class InterceptInputConnectionIntegrationTest {
textView.text.dumpSpans().joinToString(",\n"), equalTo(
"""
hello: android.widget.TextView.ChangeWatcher (0-5) fl=#6553618,
hello: io.element.android.wysiwyg.view.spans.OrderedListSpan (0-5) fl=#34,
hello: io.element.android.wysiwyg.view.spans.OrderedListSpan (0-5) fl=#17,
hello: android.text.style.UnderlineSpan (0-5) fl=#289,
hello: android.view.inputmethod.ComposingText (0-5) fl=#289,
hello: android.text.method.TextKeyListener (0-5) fl=#18,
Expand All @@ -244,7 +245,7 @@ class InterceptInputConnectionIntegrationTest {
textView.text.dumpSpans(), equalTo(
listOf(
"😋😋: android.widget.TextView.ChangeWatcher (0-4) fl=#6553618",
"😋😋: io.element.android.wysiwyg.view.spans.OrderedListSpan (0-4) fl=#34",
"😋😋: io.element.android.wysiwyg.view.spans.OrderedListSpan (0-4) fl=#17",
"😋😋: android.text.style.UnderlineSpan (0-4) fl=#289",
"😋😋: android.view.inputmethod.ComposingText (0-4) fl=#289",
"😋😋: android.text.method.TextKeyListener (0-4) fl=#18",
Expand All @@ -270,7 +271,7 @@ class InterceptInputConnectionIntegrationTest {
textView.text.dumpSpans(), equalTo(
listOf(
"hello: android.widget.TextView.ChangeWatcher (0-5) fl=#6553618",
"hello: io.element.android.wysiwyg.view.spans.CodeBlockSpan (0-5) fl=#33",
"hello: io.element.android.wysiwyg.view.spans.CodeBlockSpan (0-5) fl=#17",
"hello: android.text.style.UnderlineSpan (0-5) fl=#289",
"hello: android.view.inputmethod.ComposingText (0-5) fl=#289",
"hello: android.text.method.TextKeyListener (0-5) fl=#18",
Expand Down Expand Up @@ -317,7 +318,7 @@ class InterceptInputConnectionIntegrationTest {
textView.text.dumpSpans(), equalTo(
listOf(
"Test\n$NBSP: android.widget.TextView.ChangeWatcher (0-6) fl=#6553618",
"Test\n$NBSP: io.element.android.wysiwyg.view.spans.CodeBlockSpan (0-6) fl=#33",
"Test\n$NBSP: io.element.android.wysiwyg.view.spans.CodeBlockSpan (0-6) fl=#17",
"$NBSP: io.element.android.wysiwyg.view.spans.ExtraCharacterSpan (5-6) fl=#17",
"Test\n$NBSP: android.text.method.TextKeyListener (0-6) fl=#18",
"Test\n$NBSP: android.widget.Editor.SpanController (0-6) fl=#18",
Expand All @@ -335,7 +336,7 @@ class InterceptInputConnectionIntegrationTest {
textView.text.dumpSpans(), equalTo(
listOf(
"Test\n$NBSP: android.widget.TextView.ChangeWatcher (0-6) fl=#6553618",
"Test: io.element.android.wysiwyg.view.spans.CodeBlockSpan (0-4) fl=#33",
"Test: io.element.android.wysiwyg.view.spans.CodeBlockSpan (0-4) fl=#17",
"$NBSP: io.element.android.wysiwyg.view.spans.ExtraCharacterSpan (5-6) fl=#17",
"Test\n$NBSP: android.text.method.TextKeyListener (0-6) fl=#18",
"Test\n$NBSP: android.widget.Editor.SpanController (0-6) fl=#18",
Expand All @@ -360,7 +361,7 @@ class InterceptInputConnectionIntegrationTest {
textView.text.dumpSpans().joinToString(",\n"), equalTo(
"""
hello: android.widget.TextView.ChangeWatcher (0-5) fl=#6553618,
hello: io.element.android.wysiwyg.view.spans.QuoteSpan (0-5) fl=#33,
hello: io.element.android.wysiwyg.view.spans.QuoteSpan (0-5) fl=#65553,
hello: android.text.style.UnderlineSpan (0-5) fl=#289,
hello: android.view.inputmethod.ComposingText (0-5) fl=#289,
hello: android.text.method.TextKeyListener (0-5) fl=#18,
Expand Down Expand Up @@ -407,7 +408,7 @@ class InterceptInputConnectionIntegrationTest {
textView.text.dumpSpans(), equalTo(
listOf(
"Test\n$NBSP: android.widget.TextView.ChangeWatcher (0-6) fl=#6553618",
"Test\n$NBSP: io.element.android.wysiwyg.view.spans.QuoteSpan (0-6) fl=#33",
"Test\n$NBSP: io.element.android.wysiwyg.view.spans.QuoteSpan (0-6) fl=#65553",
"$NBSP: io.element.android.wysiwyg.view.spans.ExtraCharacterSpan (5-6) fl=#17",
"Test\n$NBSP: android.text.method.TextKeyListener (0-6) fl=#18",
"Test\n$NBSP: android.widget.Editor.SpanController (0-6) fl=#18",
Expand All @@ -425,7 +426,7 @@ class InterceptInputConnectionIntegrationTest {
textView.text.dumpSpans(), equalTo(
listOf(
"Test\n$NBSP: android.widget.TextView.ChangeWatcher (0-6) fl=#6553618",
"Test: io.element.android.wysiwyg.view.spans.QuoteSpan (0-4) fl=#33",
"Test: io.element.android.wysiwyg.view.spans.QuoteSpan (0-4) fl=#65553",
"$NBSP: io.element.android.wysiwyg.view.spans.ExtraCharacterSpan (5-6) fl=#17",
"Test\n$NBSP: android.text.method.TextKeyListener (0-6) fl=#18",
"Test\n$NBSP: android.widget.Editor.SpanController (0-6) fl=#18",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package io.element.android.wysiwyg

import android.text.Editable
import android.text.TextWatcher
import io.element.android.wysiwyg.utils.LoggingConfig
import timber.log.Timber
import java.util.concurrent.atomic.AtomicBoolean

Expand All @@ -14,8 +15,6 @@ internal class EditorTextWatcher: TextWatcher {

val isInEditorChange get() = updateIsFromEditor.get()

var enableDebugLogs = false

private var beforeText: CharSequence? = null

/**
Expand Down Expand Up @@ -53,7 +52,7 @@ internal class EditorTextWatcher: TextWatcher {
}

override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
if (enableDebugLogs) {
if (LoggingConfig.enableDebugLogs) {
Timber.v("beforeTextChanged | text: \"$s\", start: $start, count: $count, after: $after")
}
if (!updateIsFromEditor.get()) {
Expand All @@ -62,7 +61,7 @@ internal class EditorTextWatcher: TextWatcher {
}

override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
if (enableDebugLogs) {
if (LoggingConfig.enableDebugLogs) {
Timber.v("onTextChanged | text: \"$s\", start: $start, before: $before, count: $count")
}
if (!updateIsFromEditor.get()) {
Expand All @@ -72,7 +71,7 @@ internal class EditorTextWatcher: TextWatcher {
}

override fun afterTextChanged(s: Editable?) {
if (enableDebugLogs) {
if (LoggingConfig.enableDebugLogs) {
Timber.v("afterTextChanged")
}
if (!updateIsFromEditor.get()) {
Expand Down
Loading

0 comments on commit 6f982ac

Please sign in to comment.