Skip to content

Commit 97c03ca

Browse files
Gilles DebunneAndroid (Google) Code Review
authored andcommitted
Merge "Do not notify text watchers when replace is a no-op"
2 parents 069ac9a + d60da05 commit 97c03ca

File tree

1 file changed

+20
-0
lines changed

1 file changed

+20
-0
lines changed

core/java/android/text/SpannableStringBuilder.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,12 @@ public SpannableStringBuilder replace(final int start, final int end,
428428
final int origLen = end - start;
429429
final int newLen = tbend - tbstart;
430430

431+
if (origLen == 0 && newLen == 0 && !hasNonExclusiveExclusiveSpanAt(tb, tbstart)) {
432+
// This is a no-op iif there are no spans in tb that would be added (with a 0-length)
433+
// Early exit so that the text watchers do not get notified
434+
return this;
435+
}
436+
431437
TextWatcher[] textWatchers = getSpans(start, start + origLen, TextWatcher.class);
432438
sendBeforeTextChanged(textWatchers, start, origLen, newLen);
433439

@@ -470,6 +476,20 @@ public SpannableStringBuilder replace(final int start, final int end,
470476
return this;
471477
}
472478

479+
private static boolean hasNonExclusiveExclusiveSpanAt(CharSequence text, int offset) {
480+
if (text instanceof Spanned) {
481+
Spanned spanned = (Spanned) text;
482+
Object[] spans = spanned.getSpans(offset, offset, Object.class);
483+
final int length = spans.length;
484+
for (int i = 0; i < length; i++) {
485+
Object span = spans[i];
486+
int flags = spanned.getSpanFlags(span);
487+
if (flags != Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) return true;
488+
}
489+
}
490+
return false;
491+
}
492+
473493
private void sendToSpanWatchers(int replaceStart, int replaceEnd, int nbNewChars) {
474494
for (int i = 0; i < mSpanCountBeforeAdd; i++) {
475495
int spanStart = mSpanStarts[i];

0 commit comments

Comments
 (0)