From 79e17406544063392986247ebdf129c301cf7b0f Mon Sep 17 00:00:00 2001 From: Mario Zorz Date: Fri, 29 Mar 2019 09:10:52 -0300 Subject: [PATCH] added disableCrashPreventerInputFilter and disableMediaDeletedListener to prevent inputFilter from being called twice and MediaDeletedListener from being mistakingly called by a non-user operation --- .../kotlin/org/wordpress/aztec/AztecText.kt | 36 ++++++++++++++++++- ...DeleteMediaElementWatcherAPI25AndHigher.kt | 4 +++ .../DeleteMediaElementWatcherPreAPI25.kt | 4 +++ 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/aztec/src/main/kotlin/org/wordpress/aztec/AztecText.kt b/aztec/src/main/kotlin/org/wordpress/aztec/AztecText.kt index e364cd7f8..a8d9c67cd 100644 --- a/aztec/src/main/kotlin/org/wordpress/aztec/AztecText.kt +++ b/aztec/src/main/kotlin/org/wordpress/aztec/AztecText.kt @@ -224,6 +224,8 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown private var consumeSelectionChangedEvent: Boolean = false private var isInlineTextHandlerEnabled: Boolean = true private var bypassObservationQueue: Boolean = false + private var bypassMediaDeletedListener: Boolean = false + private var bypassCrashPreventerInputFilter: Boolean = false var initialEditorContentParsedSHA256: ByteArray = ByteArray(0) @@ -456,22 +458,34 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown // https://android-review.googlesource.com/c/platform/frameworks/base/+/634929 val dynamicLayoutCrashPreventer = InputFilter { source, start, end, dest, dstart, dend -> var temp = source - if (dest.length > dend+1) { + if (dest.length > dend+1 && !bypassCrashPreventerInputFilter) { // if there are any images right after the destination position, hack the text val spans = dest.getSpans(dstart, dend+1, AztecImageSpan::class.java) if (spans.isNotEmpty()) { // test: is this an insertion? if (dstart == dend) { + + // prevent this filter from running twice when `text.insert()` gets called a few lines below + disableCrashPreventerInputFilter() + // disable MediaDeleted listener before operating on content + disableMediaDeletedListener() + // take the source (that is, what is being inserted), and append the Image to it. We will delete // the original Image later so to not have a duplicate. // use Spannable to copy / keep the current spans temp = SpannableStringBuilder(source).append(dest.subSequence(dend, dend+1)) + // delete the original AztecImageSpan text.delete(dend, dend+1) // now insert both the new insertion _and_ the original AztecImageSpan text.insert(dend, temp) temp = "" // discard the original source parameter as an ouput from this InputFilter + + // re-enable MediaDeleted listener + enableMediaDeletedListener() + // re-enable this very filter + enableCrashPreventerInputFilter() } } } @@ -1340,6 +1354,26 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown bypassObservationQueue = false } + fun disableCrashPreventerInputFilter() { + bypassCrashPreventerInputFilter = true + } + + fun enableCrashPreventerInputFilter() { + bypassCrashPreventerInputFilter = false + } + + fun disableMediaDeletedListener() { + bypassMediaDeletedListener = true + } + + fun enableMediaDeletedListener() { + bypassMediaDeletedListener = false + } + + fun isMediaDeletedListenerDisabled(): Boolean { + return bypassMediaDeletedListener + } + fun isTextChangedListenerDisabled(): Boolean { return consumeEditEvent } diff --git a/aztec/src/main/kotlin/org/wordpress/aztec/watchers/DeleteMediaElementWatcherAPI25AndHigher.kt b/aztec/src/main/kotlin/org/wordpress/aztec/watchers/DeleteMediaElementWatcherAPI25AndHigher.kt index d6e2506df..dd1844fa1 100644 --- a/aztec/src/main/kotlin/org/wordpress/aztec/watchers/DeleteMediaElementWatcherAPI25AndHigher.kt +++ b/aztec/src/main/kotlin/org/wordpress/aztec/watchers/DeleteMediaElementWatcherAPI25AndHigher.kt @@ -17,6 +17,10 @@ class DeleteMediaElementWatcherAPI25AndHigher(aztecText: AztecText) : TextWatche return } + if (aztecTextRef.get()?.isMediaDeletedListenerDisabled() ?: true) { + return + } + if (count > 0) { deleted = true diff --git a/aztec/src/main/kotlin/org/wordpress/aztec/watchers/DeleteMediaElementWatcherPreAPI25.kt b/aztec/src/main/kotlin/org/wordpress/aztec/watchers/DeleteMediaElementWatcherPreAPI25.kt index 318a0fc9f..880569278 100644 --- a/aztec/src/main/kotlin/org/wordpress/aztec/watchers/DeleteMediaElementWatcherPreAPI25.kt +++ b/aztec/src/main/kotlin/org/wordpress/aztec/watchers/DeleteMediaElementWatcherPreAPI25.kt @@ -14,6 +14,10 @@ class DeleteMediaElementWatcherPreAPI25(aztecText: AztecText) : TextWatcher { return } + if (aztecTextRef.get()?.isMediaDeletedListenerDisabled() ?: true) { + return + } + if (count > 0) { aztecTextRef.get()?.text?.getSpans(start, start + count, AztecMediaSpan::class.java) ?.forEach {