Skip to content

Commit

Permalink
Merge pull request #834 from wordpress-mobile/fix/ime-iob-fix
Browse files Browse the repository at this point in the history
Fix/ime iob fix
  • Loading branch information
hypest authored Oct 16, 2019
2 parents a6c634c + 2169aff commit 1f257c7
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 1 deletion.
46 changes: 46 additions & 0 deletions aztec/src/main/kotlin/org/wordpress/aztec/AztecText.kt
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ import android.view.MotionEvent
import android.view.View
import android.view.WindowManager
import android.view.inputmethod.BaseInputConnection
import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputConnection
import android.widget.CheckBox
import android.widget.EditText
import android.widget.Toast
Expand All @@ -70,6 +72,7 @@ import org.wordpress.aztec.handlers.ListHandler
import org.wordpress.aztec.handlers.ListItemHandler
import org.wordpress.aztec.handlers.PreformatHandler
import org.wordpress.aztec.handlers.QuoteHandler
import org.wordpress.aztec.ime.EditorInfoUtils
import org.wordpress.aztec.plugins.IAztecPlugin
import org.wordpress.aztec.plugins.IToolbarButton
import org.wordpress.aztec.source.Format
Expand Down Expand Up @@ -118,6 +121,7 @@ import org.wordpress.aztec.watchers.event.text.BeforeTextChangedEventData
import org.wordpress.aztec.watchers.event.text.OnTextChangedEventData
import org.wordpress.aztec.watchers.event.text.TextWatcherEvent
import org.xml.sax.Attributes
import java.lang.ref.WeakReference
import java.security.MessageDigest
import java.security.NoSuchAlgorithmException
import java.util.ArrayList
Expand Down Expand Up @@ -291,6 +295,9 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown

private var focusOnVisible = true

var inputConnectionRef: WeakReference<InputConnection>? = null
var inputConnectionEditorInfo: EditorInfo? = null

interface OnSelectionChangedListener {
fun onSelectionChanged(selStart: Int, selEnd: Int)
}
Expand Down Expand Up @@ -660,6 +667,45 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown
}
}

override fun onCreateInputConnection(outAttrs: EditorInfo) : InputConnection {
// limiting the reuseInputConnection fix for Anroid 8.0.0 for now
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.O) {
return handleReuseInputConnection(outAttrs)
}

return super.onCreateInputConnection(outAttrs)
}

private fun handleReuseInputConnection(outAttrs: EditorInfo) : InputConnection {
// initialize inputConnectionEditorInfo
if (inputConnectionEditorInfo == null) {
inputConnectionEditorInfo = outAttrs
}

// now init the InputConnection, or replace if EditorInfo contains anything different
if (inputConnectionRef?.get() == null || !EditorInfoUtils.areEditorInfosTheSame(outAttrs, inputConnectionEditorInfo!!)) {
// we have a new InputConnection to create, save the new EditorInfo data and create it
// we make a copy of the parameters being received, because super.onCreateInputConnection may make changes
// to EditorInfo params being sent to it, and we want to preserve the same data we received in order
// to compare.
// (see https://android.googlesource.com/platform/frameworks/base/+/jb-mr0-release/core/java/android/widget/
// TextView.java#5404)
inputConnectionEditorInfo = EditorInfoUtils.copyEditorInfo(outAttrs)
val localInputConnection = super.onCreateInputConnection(outAttrs)
if (localInputConnection == null) {
// in case super returns null, let's just observe the base implementation, no need to make
// an InputConnectionWrapper of a null target
return localInputConnection
}
// if non null, wrap the new InputConnection around our wrapper (used for logging purposes only)
//inputConnection = AztecTextInputConnectionWrapper(localInputConnection, this)
inputConnectionRef = WeakReference(localInputConnection)
}

// return the existing inputConnection
return inputConnectionRef?.get()!!
}

override fun onRestoreInstanceState(state: Parcelable?) {
disableTextChangedListener()

Expand Down
55 changes: 55 additions & 0 deletions aztec/src/main/kotlin/org/wordpress/aztec/ime/EditorInfoUtils.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package org.wordpress.aztec.ime

import android.os.Build
import android.view.inputmethod.EditorInfo
import java.util.Arrays

object EditorInfoUtils {
@JvmStatic
fun areEditorInfosTheSame(ed1: EditorInfo, ed2: EditorInfo): Boolean {
if (ed1 == ed2) {
return true
}

if (ed1.actionId == ed2.actionId
&& (ed1.actionLabel != null && ed1.actionLabel.equals(ed2.actionLabel) || ed1.actionLabel == null && ed2.actionLabel == null)
&& ed1.inputType == ed2.inputType
&& ed1.imeOptions == ed2.imeOptions
&& (ed1.privateImeOptions != null && ed1.privateImeOptions.equals(ed2.privateImeOptions) || ed1.privateImeOptions == null && ed2.privateImeOptions == null)
&& ed1.initialSelStart == ed2.initialSelStart
&& ed1.initialSelEnd == ed2.initialSelEnd
&& ed1.initialCapsMode == ed2.initialCapsMode
&& ed1.fieldId == ed2.fieldId
) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
// specific comparisons here
if (ed1.contentMimeTypes != null && ed2.contentMimeTypes != null) {
return Arrays.equals(ed1.contentMimeTypes, ed2.contentMimeTypes)
}
}
return true
}
return false
}

@JvmStatic
fun copyEditorInfo(ed1: EditorInfo) : EditorInfo {
val copy = EditorInfo()
copy.actionId = ed1.actionId
copy.actionLabel = ed1.actionLabel?.toString()
copy.inputType = ed1.inputType
copy.imeOptions = ed1.imeOptions
copy.privateImeOptions = ed1.privateImeOptions?.toString()
copy.initialSelStart = ed1.initialSelStart
copy.initialSelEnd = ed1.initialSelEnd
copy.initialCapsMode = ed1.initialCapsMode
copy.fieldId = ed1.fieldId
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
// specific comparisons here
if (ed1.contentMimeTypes != null) {
copy.contentMimeTypes = Arrays.copyOf(ed1.contentMimeTypes, ed1.contentMimeTypes.size)
}
}
return copy
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ class CssUnderlinePlugin : ISpanPostprocessor, ISpanPreprocessor {
if (hiddenSpan.TAG == SPAN_TAG) {
val parentStyle = hiddenSpan.attributes.getValue(CssStyleFormatter.STYLE_ATTRIBUTE)
val childStyle = calypsoUnderlineSpan.attributes.getValue(CssStyleFormatter.STYLE_ATTRIBUTE)
hiddenSpan.attributes.setValue(CssStyleFormatter.STYLE_ATTRIBUTE, CssStyleFormatter.mergeStyleAttributes(parentStyle, childStyle))
if (parentStyle != null && childStyle != null) {
hiddenSpan.attributes.setValue(CssStyleFormatter.STYLE_ATTRIBUTE, CssStyleFormatter.mergeStyleAttributes(parentStyle, childStyle))
}

// remove the extra child span
spannable.removeSpan(calypsoUnderlineSpan)
Expand Down

0 comments on commit 1f257c7

Please sign in to comment.