Skip to content

Commit ab43e40

Browse files
committed
Modify DynamicLayout crash preventer to address more cases.
1 parent a3f5b83 commit ab43e40

File tree

1 file changed

+16
-15
lines changed

1 file changed

+16
-15
lines changed

aztec/src/main/kotlin/org/wordpress/aztec/AztecText.kt

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -455,29 +455,27 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown
455455
// https://android-review.googlesource.com/c/platform/frameworks/base/+/634929
456456
val dynamicLayoutCrashPreventer = InputFilter { source, start, end, dest, dstart, dend ->
457457
var temp : CharSequence? = null
458-
if (!bypassCrashPreventerInputFilter
459-
&& dstart == dend && dest.length > dend+1
460-
&& source != Constants.NEWLINE_STRING) {
461-
// dstart == dend means this is an insertion
462-
// avoid handling anything if it's a newline
458+
if (!bypassCrashPreventerInputFilter) {
459+
463460
// if there are any images right after the destination position, hack the text
464-
val spans = dest.getSpans(dstart, dend+1, AztecImageSpan::class.java)
461+
val spans = dest.getSpans(dend, dend+1, AztecImageSpan::class.java)
465462
if (spans.isNotEmpty()) {
463+
466464
// prevent this filter from running twice when `text.insert()` gets called a few lines below
467465
disableCrashPreventerInputFilter()
468466
// disable MediaDeleted listener before operating on content
469467
disableMediaDeletedListener()
470468

471-
// take the source (that is, what is being inserted), and append the Image to it. We will delete
472-
// the original Image later so to not have a duplicate.
473-
// use Spannable to copy / keep the current spans
474-
temp = SpannableStringBuilder(source).append(dest.subSequence(dend, dend+1))
469+
// create a new Spannable to perform the text change here
470+
var newText = SpannableStringBuilder(dest.subSequence(0, dstart))
471+
.append(source.subSequence(start, end))
472+
.append(dest.subSequence(dend, dest.length));
473+
474+
// force a history update to ensure the change is recorded
475+
history.beforeTextChanged(this@AztecText)
475476

476-
// delete the original AztecImageSpan
477-
text.delete(dend, dend+1)
478-
// now insert both the new insertion _and_ the original AztecImageSpan
479-
text.insert(dend, temp)
480-
temp = "" // discard the original source parameter as an ouput from this InputFilter
477+
// use HTML from the new text to set the state of the editText directly
478+
fromHtml(toFormattedHtml(newText), false)
481479

482480
// re-enable MediaDeleted listener
483481
enableMediaDeletedListener()
@@ -1577,8 +1575,11 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown
15771575
(max == length || (length == 1 && text.toString() == Constants.END_OF_BUFFER_MARKER_STRING))) {
15781576
setText(Constants.REPLACEMENT_MARKER_STRING)
15791577
} else {
1578+
// prevent changes here from triggering the crash preventer
1579+
disableCrashPreventerInputFilter()
15801580
editable.delete(min, max)
15811581
editable.insert(min, Constants.REPLACEMENT_MARKER_STRING)
1582+
enableCrashPreventerInputFilter()
15821583
}
15831584

15841585
// don't let the pasted text be included in any existing style

0 commit comments

Comments
 (0)