@@ -3,7 +3,7 @@ package org.wordpress.aztec
33import android.os.Build
44import android.os.Bundle
55import android.text.Editable
6- import android.text.SpannableStringBuilder
6+ import android.text.Selection
77import android.text.Spanned
88import android.text.TextUtils
99import android.text.style.SuggestionSpan
@@ -15,8 +15,6 @@ import android.view.inputmethod.ExtractedText
1515import android.view.inputmethod.ExtractedTextRequest
1616import android.view.inputmethod.InputConnection
1717import android.view.inputmethod.InputContentInfo
18- import org.wordpress.aztec.Constants.ZWJ_CHAR
19- import org.wordpress.aztec.spans.IAztecSpan
2018
2119/* *
2220 * Wrapper around proprietary Samsung InputConnection. Forwards all the calls to it, except for getExtractedText
@@ -78,34 +76,52 @@ class SamsungInputConnection(
7876 }
7977
8078 override fun commitText (text : CharSequence? , newCursorPosition : Int ): Boolean {
81- val isSameStringValue = text.toString().replace(ZWJ_CHAR .toString(), " " , true ) ==
82- editable.toString().replace(ZWJ_CHAR .toString(), " " , true )
8379 val incomingTextHasSuggestions = text is Spanned &&
8480 text.getSpans(0 , text.length, SuggestionSpan ::class .java).isNotEmpty()
8581
86- // Despite returning null from getExtractedText, in some cases Grammarly still tries to replace content of the
87- // editor with own content containing suggestions. This mostly works ok, but Aztec spans are finicky, and tend
88- // to get messed when content of the editor is replaced. In this method we remove Aztec spans before committing
89- // the change, and reapply them afterward
90- if (isSameStringValue && incomingTextHasSuggestions) {
91- // create a clean spannable string from editable to temporarily hold spans
92- val tempString = SpannableStringBuilder (editable.toString())
93-
94- // store Aztec and Suggestions spans in temp string
95- TextUtils .copySpansFrom(editable, 0 , editable.length, IAztecSpan ::class .java, tempString, 0 )
96- TextUtils .copySpansFrom(text as Spanned , 0 , editable.length, SuggestionSpan ::class .java, tempString, 0 )
97-
98- // remove all the Aztec spans from the current content of editor
99- editable.getSpans(0 , editable.length, IAztecSpan ::class .java).forEach { editable.removeSpan(it) }
100-
101- // commit the text
102- val result = baseInputConnection.commitText(text, newCursorPosition)
103-
104- // re-add the spans we removed before committing the text
105- TextUtils .copySpansFrom(tempString, 0 , editable.length, IAztecSpan ::class .java, editable, 0 )
106- TextUtils .copySpansFrom(tempString, 0 , editable.length, SuggestionSpan ::class .java, editable, 0 )
107-
108- return result
82+ // Sometime spellchecker tries to commit partial text with suggestions. This mostly works ok,
83+ // but Aztec spans are finicky, and tend to get messed when content of the editor is replaced.
84+ // In this method we do everything replaceText method of EditableInputConnection does, apart from actually
85+ // replacing text. Instead we copy the suggestions from incoming text into editor directly.
86+ if (incomingTextHasSuggestions) {
87+ // delete composing text set previously.
88+ var composingSpanStart = getComposingSpanStart(editable)
89+ var composingSpanEnd = getComposingSpanEnd(editable)
90+
91+ if (composingSpanEnd < composingSpanStart) {
92+ val tmp = composingSpanStart
93+ composingSpanStart = composingSpanEnd
94+ composingSpanEnd = tmp
95+ }
96+
97+ if (composingSpanStart != - 1 && composingSpanEnd != - 1 ) {
98+ removeComposingSpans(editable)
99+ } else {
100+ composingSpanStart = Selection .getSelectionStart(editable)
101+ composingSpanEnd = Selection .getSelectionEnd(editable)
102+ if (composingSpanStart < 0 ) composingSpanStart = 0
103+ if (composingSpanEnd < 0 ) composingSpanEnd = 0
104+ if (composingSpanEnd < composingSpanStart) {
105+ val tmp = composingSpanStart
106+ composingSpanStart = composingSpanEnd
107+ composingSpanEnd = tmp
108+ }
109+ }
110+
111+ var cursorPosition = newCursorPosition
112+ cursorPosition + = if (cursorPosition > 0 ) {
113+ composingSpanEnd - 1
114+ } else {
115+ composingSpanStart
116+ }
117+ if (newCursorPosition < 0 ) cursorPosition = 0
118+ if (newCursorPosition > editable.length) cursorPosition = editable.length
119+ Selection .setSelection(editable, cursorPosition)
120+
121+ TextUtils .copySpansFrom(text as Spanned , 0 , text.length, SuggestionSpan ::class .java, editable,
122+ composingSpanStart)
123+
124+ return true
109125 }
110126 return baseInputConnection.commitText(text, newCursorPosition)
111127 }
0 commit comments