Bug 1351170 - 3. Do more to synchronize spans to shadow text; r=esawin
There are some situations where spans are not properly synced from
current text to shadow text. This patch takes more steps to make sure
spans are synchronized.
MozReview-Commit-ID: 1xhsJllE7Ro
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoEditable.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoEditable.java
@@ -288,21 +288,31 @@ final class GeckoEditable extends IGecko
}
// Copy the portion of the current text that has changed over to the shadow
// text, with consideration for any concurrent changes in the shadow text.
final int start = Math.min(mShadowStart, mCurrentStart);
final int shadowEnd = mShadowNewEnd + Math.max(0, mCurrentOldEnd - mShadowOldEnd);
final int currentEnd = mCurrentNewEnd + Math.max(0, mShadowOldEnd - mCurrentOldEnd);
- // Perform replacement in two steps (delete and insert) so that old spans are
- // properly deleted before identical new spans are inserted. Otherwise the new
- // spans won't be inserted due to the text already having the old spans.
- mShadowText.delete(start, shadowEnd);
- mShadowText.insert(start, mCurrentText, start, currentEnd);
+ // Remove identical spans that are in the new text from the old text.
+ // Otherwise the new spans won't be inserted due to the text already having
+ // the old spans.
+ Object[] spans = mCurrentText.getSpans(start, currentEnd, Object.class);
+ for (final Object span : spans) {
+ mShadowText.removeSpan(span);
+ }
+
+ // Also remove existing spans that are no longer in the new text.
+ spans = mShadowText.getSpans(start, shadowEnd, Object.class);
+ for (final Object span : spans) {
+ mShadowText.removeSpan(span);
+ }
+
+ mShadowText.replace(start, shadowEnd, mCurrentText, start, currentEnd);
// SpannableStringBuilder has some internal logic to fix up selections, but we
// don't want that, so we always fix up the selection a second time.
final int selStart = Selection.getSelectionStart(mCurrentText);
final int selEnd = Selection.getSelectionEnd(mCurrentText);
Selection.setSelection(mShadowText, selStart, selEnd);
if (DEBUG && !checkEqualText(mShadowText, mCurrentText)) {