Apply spans reversed

This commit is contained in:
M66B 2020-04-24 18:05:50 +02:00
parent 5adee09a3f
commit 7628909dd0
1 changed files with 31 additions and 12 deletions

View File

@ -1767,6 +1767,7 @@ public class HtmlHelper {
if (experiments) {
// https://developer.android.com/guide/topics/text/spans
SpannableStringBuilder ssb = new SpannableStringBuilder();
List<SpanHolder> 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;
}
}
}