@@ -4,6 +4,7 @@ import android.app.Application;
import android.graphics.Typeface;
import android.text.Spanned;
import android.text.SpannableStringBuilder;
+import android.text.ParcelableSpan;
import android.text.style.AbsoluteSizeSpan;
import android.text.style.AlignmentSpan;
import android.text.style.BackgroundColorSpan;
@@ -32,9 +33,10 @@ import eu.siacs.conversations.xml.TextNode;
public class SpannedToXHTML {
private static SpannableStringBuilder cleanSpans(Spanned text) {
SpannableStringBuilder newText = new SpannableStringBuilder(text);
- SuggestionSpan[] spans = newText.getSpans(0, newText.length(), SuggestionSpan.class);
- for (SuggestionSpan span : spans) {
- newText.removeSpan(span);
+ ParcelableSpan[] spans = newText.getSpans(0, newText.length(), ParcelableSpan.class);
+ for (final var span : spans) {
+ final var userFlags = (text.getSpanFlags(span) & Spanned.SPAN_USER) >> Spanned.SPAN_USER_SHIFT;
+ if (span instanceof SuggestionSpan || userFlags == 1) newText.removeSpan(span);
}
BaseInputConnection.removeComposingSpans(newText);
return newText;
@@ -77,23 +77,27 @@ public class StylingHelper {
}
}
- public static void format(final Editable editable, int start, int end, @ColorInt int textColor) {
+ public static void format(final Editable editable, int start, int end, @ColorInt int textColor, final boolean composing) {
for (ImStyleParser.Style style : ImStyleParser.parse(editable, start, end)) {
final int keywordLength = style.getKeyword().length();
- editable.setSpan(createSpanForStyle(style), style.getStart() + keywordLength, style.getEnd() - keywordLength + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
- makeKeywordOpaque(editable, style.getStart(), style.getStart() + keywordLength, textColor);
- makeKeywordOpaque(editable, style.getEnd() - keywordLength + 1, style.getEnd() + 1, textColor);
+ editable.setSpan(createSpanForStyle(style), style.getStart() + keywordLength, style.getEnd() - keywordLength + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE | (composing ? 1 << Spanned.SPAN_USER_SHIFT : 0));
+ makeKeywordOpaque(editable, style.getStart(), style.getStart() + keywordLength, textColor, composing);
+ makeKeywordOpaque(editable, style.getEnd() - keywordLength + 1, style.getEnd() + 1, textColor, composing);
}
}
public static void format(final Editable editable, @ColorInt int textColor) {
+ format(editable, textColor, false);
+ }
+
+ public static void format(final Editable editable, @ColorInt int textColor, final boolean composing) {
int end = 0;
Message.MergeSeparator[] spans = editable.getSpans(0, editable.length() - 1, Message.MergeSeparator.class);
for (Message.MergeSeparator span : spans) {
- format(editable, end, editable.getSpanStart(span), textColor);
+ format(editable, end, editable.getSpanStart(span), textColor, composing);
end = editable.getSpanEnd(span);
}
- format(editable, end, editable.length() - 1, textColor);
+ format(editable, end, editable.length() - 1, textColor, composing);
}
public static void highlight(final TextView view, final Editable editable, final List<String> needles) {
@@ -186,11 +190,11 @@ public class StylingHelper {
};
}
- private static void makeKeywordOpaque(final Editable editable, int start, int end, @ColorInt int fallbackTextColor) {
+ private static void makeKeywordOpaque(final Editable editable, int start, int end, @ColorInt int fallbackTextColor, final boolean composing) {
QuoteSpan[] quoteSpans = editable.getSpans(start, end, QuoteSpan.class);
@ColorInt int textColor = quoteSpans.length > 0 ? quoteSpans[0].getColor() : fallbackTextColor;
@ColorInt int keywordColor = transformColor(textColor);
- editable.setSpan(new ForegroundColorSpan(keywordColor), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ editable.setSpan(new ForegroundColorSpan(keywordColor), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE | (composing ? 1 << Spanned.SPAN_USER_SHIFT : 0));
}
private static
@@ -239,7 +243,7 @@ public class StylingHelper {
@Override
public void afterTextChanged(Editable editable) {
clear(editable);
- format(editable, mEditText.getCurrentTextColor());
+ format(editable, mEditText.getCurrentTextColor(), true);
}
}
}
@@ -250,7 +250,7 @@ public class UIHelper {
fallbackImg.setBounds(0, 0, fallbackImg.getIntrinsicWidth(), fallbackImg.getIntrinsicHeight());
SpannableStringBuilder styledBody = message.getSpannableBody(null, fallbackImg);
if (textColor != 0) {
- StylingHelper.format(styledBody, 0, styledBody.length() - 1, textColor);
+ StylingHelper.format(styledBody, 0, styledBody.length() - 1, textColor, false);
}
MyLinkify.addLinks(styledBody, message.getConversation().getAccount(), message.getConversation().getJid());
SpannableStringBuilder builder = new SpannableStringBuilder();