Don't linkify inside escaped/codeblocks

(cherry picked from commit de8fb3e26599bb24b1d2b07be3a0ea410c0695c2)
This commit is contained in:
Stephen Paul Weber 2024-09-08 13:05:41 -05:00 committed by Arne
parent 26933e2d09
commit 8c6b69cbed
2 changed files with 22 additions and 2 deletions

View file

@ -32,6 +32,8 @@ package eu.siacs.conversations.ui.util;
import android.net.Uri;
import android.os.Build;
import android.text.Editable;
import android.text.Spanned;
import android.text.style.TypefaceSpan;
import android.text.style.URLSpan;
import android.text.util.Linkify;
@ -52,6 +54,7 @@ import eu.siacs.conversations.entities.Roster;
import eu.siacs.conversations.ui.text.FixedURLSpan;
import eu.siacs.conversations.utils.GeoHelper;
import eu.siacs.conversations.utils.Patterns;
import eu.siacs.conversations.utils.StylingHelper;
import eu.siacs.conversations.utils.XmppUri;
import eu.siacs.conversations.xmpp.Jid;
@ -139,7 +142,16 @@ public class MyLinkify {
public static void addLinks(Editable body, Account account, Jid context) {
addLinks(body, true);
Roster roster = account.getRoster();
urlspan:
for (final URLSpan urlspan : body.getSpans(0, body.length() - 1, URLSpan.class)) {
final var start = body.getSpanStart(urlspan);
for (final var span : body.getSpans(start, start, Object.class)) {
// instanceof TypefaceSpan is to block in XHTML code blocks. Probably a bit heavy-handed but works for now
if ((body.getSpanFlags(span) & Spanned.SPAN_USER) >> Spanned.SPAN_USER_SHIFT == StylingHelper.NOLINKIFY || span instanceof TypefaceSpan) {
body.removeSpan(urlspan);
continue urlspan;
}
}
Uri uri = Uri.parse(urlspan.getURL());
if ("xmpp".equals(uri.getScheme())) {
try {
@ -153,7 +165,7 @@ public class MyLinkify {
String display = xmppUri.toString();
if (jid.asBareJid().equals(context) && xmppUri.isAction("message") && xmppUri.getBody() != null) {
display = xmppUri.getBody();
} else if (jid.asBareJid().equals(context)) {
} else if (jid.asBareJid().equals(context) && xmppUri.parameterString().length() > 0) {
display = xmppUri.parameterString();
} else {
ListItem item = account.getBookmark(jid);

View file

@ -67,6 +67,7 @@ public class StylingHelper {
public static final int XHTML_IGNORE = 1;
public static final int XHTML_REMOVE = 2;
public static final int XHTML_EMPHASIS = 3;
public static final int NOLINKIFY = 0xf0;
private static final List<? extends Class<? extends ParcelableSpan>> SPAN_CLASSES = Arrays.asList(
StyleSpan.class,
@ -88,7 +89,14 @@ public class StylingHelper {
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 | ("*".equals(style.getKeyword()) || "_".equals(style.getKeyword()) ? XHTML_EMPHASIS << Spanned.SPAN_USER_SHIFT : 0));
editable.setSpan(
createSpanForStyle(style),
style.getStart() + keywordLength,
style.getEnd() - keywordLength + 1,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE |
("*".equals(style.getKeyword()) || "_".equals(style.getKeyword()) ? XHTML_EMPHASIS << Spanned.SPAN_USER_SHIFT : 0) |
("`".equals(style.getKeyword()) || "```".equals(style.getKeyword()) ? NOLINKIFY << Spanned.SPAN_USER_SHIFT : 0)
);
makeKeywordOpaque(editable, style.getStart(), style.getStart() + keywordLength + ("```".equals(style.getKeyword()) ? 1 : 0), textColor, composing);
makeKeywordOpaque(editable, style.getEnd() - keywordLength + 1, style.getEnd() + 1, textColor, composing);
}