From d60da058c6a9a63ef7347685f39a9dedebbc6afa Mon Sep 17 00:00:00 2001 From: Gilles Debunne Date: Wed, 18 Apr 2012 15:12:20 -0700 Subject: 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 --- core/java/android/text/SpannableStringBuilder.java | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'core/java/android') diff --git a/core/java/android/text/SpannableStringBuilder.java b/core/java/android/text/SpannableStringBuilder.java index ea9f650..c5e2c42 100644 --- a/core/java/android/text/SpannableStringBuilder.java +++ b/core/java/android/text/SpannableStringBuilder.java @@ -428,6 +428,12 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable final int origLen = end - start; final int newLen = tbend - tbstart; + if (origLen == 0 && newLen == 0 && !hasNonExclusiveExclusiveSpanAt(tb, tbstart)) { + // This is a no-op iif there are no spans in tb that would be added (with a 0-length) + // Early exit so that the text watchers do not get notified + return this; + } + TextWatcher[] textWatchers = getSpans(start, start + origLen, TextWatcher.class); sendBeforeTextChanged(textWatchers, start, origLen, newLen); @@ -470,6 +476,20 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable return this; } + private static boolean hasNonExclusiveExclusiveSpanAt(CharSequence text, int offset) { + if (text instanceof Spanned) { + Spanned spanned = (Spanned) text; + Object[] spans = spanned.getSpans(offset, offset, Object.class); + final int length = spans.length; + for (int i = 0; i < length; i++) { + Object span = spans[i]; + int flags = spanned.getSpanFlags(span); + if (flags != Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) return true; + } + } + return false; + } + private void sendToSpanWatchers(int replaceStart, int replaceEnd, int nbNewChars) { for (int i = 0; i < mSpanCountBeforeAdd; i++) { int spanStart = mSpanStarts[i]; -- cgit v1.1