Don't put the composing-preview spans into xhtml for now

Stephen Paul Weber created

Change summary

src/cheogram/java/com/cheogram/android/SpannedToXHTML.java    |  8 +
src/main/java/eu/siacs/conversations/utils/StylingHelper.java | 22 ++--
src/main/java/eu/siacs/conversations/utils/UIHelper.java      |  2 
3 files changed, 19 insertions(+), 13 deletions(-)

Detailed changes

src/cheogram/java/com/cheogram/android/SpannedToXHTML.java 🔗

@@ -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;

src/main/java/eu/siacs/conversations/utils/StylingHelper.java 🔗

@@ -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);
 		}
 	}
 }

src/main/java/eu/siacs/conversations/utils/UIHelper.java 🔗

@@ -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();