Skip to content

Commit d60da05

Browse files
author
Gilles Debunne
committed
Do not notify text watchers when replace is a no-op
Bug 6344997 The early exit we used to do when both replaced and replacement strings were empty has been added back. Only this time it correctly also makes sure no spans from the replacement string would get added with a 0-length. Change-Id: Ifc38a7e3619c57aa7647c0a8e63d7627d86f1036
1 parent 9098528 commit d60da05

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)