diff --git a/app/src/main/java/eu/faircode/email/HtmlHelper.java b/app/src/main/java/eu/faircode/email/HtmlHelper.java index e3bac28136..845bbb7a8b 100644 --- a/app/src/main/java/eu/faircode/email/HtmlHelper.java +++ b/app/src/main/java/eu/faircode/email/HtmlHelper.java @@ -1767,6 +1767,7 @@ public class HtmlHelper { if (experiments) { // https://developer.android.com/guide/topics/text/spans SpannableStringBuilder ssb = new SpannableStringBuilder(); + List holders = new ArrayList<>(); NodeTraversor.traverse(new NodeVisitor() { @Override @@ -1781,7 +1782,7 @@ public class HtmlHelper { ? context.getDrawable(R.drawable.baseline_broken_image_24) : imageGetter.getDrawable(src)); ssb.append("\uFFFC"); // Object replacement character - ssb.setSpan(new ImageSpan(d, src), ssb.length() - 1, ssb.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + holders.add(new SpanHolder(new ImageSpan(d, src), ssb.length() - 1, ssb.length())); break; } } else if (node instanceof TextNode) { @@ -1798,22 +1799,22 @@ public class HtmlHelper { switch (element.tagName()) { case "a": String href = element.attr("href"); - ssb.setSpan(new URLSpan(href), start, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + holders.add(new SpanHolder(new URLSpan(href), start, ssb.length())); break; case "body": // Do nothing break; case "big": - ssb.setSpan(new RelativeSizeSpan(FONT_LARGE), start, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + holders.add(new SpanHolder(new RelativeSizeSpan(FONT_LARGE), start, ssb.length())); break; case "blockquote": - ssb.setSpan(new QuoteSpan(), start, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + holders.add(new SpanHolder(new QuoteSpan(), start, ssb.length())); break; case "br": ssb.append("\n"); break; case "em": - ssb.setSpan(new StyleSpan(Typeface.ITALIC), start, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + holders.add(new SpanHolder(new StyleSpan(Typeface.ITALIC), start, ssb.length())); break; case "h1": case "h2": @@ -1822,23 +1823,23 @@ public class HtmlHelper { case "h5": case "h6": int level = element.tagName().charAt(1) - '1'; - ssb.setSpan(new RelativeSizeSpan(HEADING_SIZES[level]), start, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - ssb.setSpan(new StyleSpan(Typeface.BOLD), start, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + holders.add(new SpanHolder(new RelativeSizeSpan(HEADING_SIZES[level]), start, ssb.length())); + holders.add(new SpanHolder(new StyleSpan(Typeface.BOLD), start, ssb.length())); break; case "img": // Do nothing break; case "small": - ssb.setSpan(new RelativeSizeSpan(FONT_SMALL), start, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + holders.add(new SpanHolder(new RelativeSizeSpan(FONT_SMALL), start, ssb.length())); break; case "span": // Do nothing break; case "strong": - ssb.setSpan(new StyleSpan(Typeface.BOLD), start, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + holders.add(new SpanHolder(new StyleSpan(Typeface.BOLD), start, ssb.length())); break; case "u": - ssb.setSpan(new UnderlineSpan(), start, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + holders.add(new SpanHolder(new UnderlineSpan(), start, ssb.length())); break; default: Log.e("Unknown tag=" + element.tagName()); @@ -1854,11 +1855,11 @@ public class HtmlHelper { switch (key) { case "color": int color = Integer.parseInt(value.substring(1), 16) | 0xFF000000; - ssb.setSpan(new ForegroundColorSpan(color), start, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + holders.add(new SpanHolder(new ForegroundColorSpan(color), start, ssb.length())); break; case "text-decoration": if ("line-through".equals(value)) - ssb.setSpan(new StrikethroughSpan(), start, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + holders.add(new SpanHolder(new StrikethroughSpan(), start, ssb.length())); break; } } @@ -1867,6 +1868,10 @@ public class HtmlHelper { } }, document.body()); + Collections.reverse(holders); + for (SpanHolder holder : holders) + ssb.setSpan(holder.span, holder.start, holder.end, holder.flags); + return ssb; } else return fromHtml(document.html(), imageGetter, null); @@ -1925,4 +1930,18 @@ public class HtmlHelper { spanned.getSpanFlags(spans[i])); return reverse; } + + private static class SpanHolder { + Object span; + int start; + int end; + int flags; + + SpanHolder(Object span, int start, int end) { + this.span = span; + this.start = start; + this.end = end; + this.flags = Spanned.SPAN_EXCLUSIVE_EXCLUSIVE; + } + } }