blob: b286bc8e1cdca612e6b18a3f34fd866384ff96d1 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.autofill_assistant;
import android.text.method.LinkMovementMethod;
import android.text.style.StyleSpan;
import android.widget.TextView;
import androidx.annotation.Nullable;
import org.chromium.base.Callback;
import org.chromium.ui.text.NoUnderlineClickableSpan;
import org.chromium.ui.text.SpanApplier;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Common text utilities used by autofill assistant.
*/
public class AssistantTextUtils {
/** Bold tags of the form <b>...</b>. */
private static final SpanApplier.SpanInfo BOLD_SPAN_INFO =
new SpanApplier.SpanInfo("<b>", "</b>", new StyleSpan(android.graphics.Typeface.BOLD));
/** Links of the form <link0>...</link0>. */
private static final Pattern LINK_PATTERN = Pattern.compile("<link(\\d+)>");
/**
* Sets the text of {@code view} by automatically applying all special appearance tags in {@code
* text}.
*
* Special appearance tags are of the form <b></b> or <link0></link0>. For links, a callback can
* be provided.
*/
public static void applyVisualAppearanceTags(
TextView view, String text, @Nullable Callback<Integer> linkCallback) {
List<SpanApplier.SpanInfo> spans = new ArrayList<>();
if (text.contains("<b>")) {
spans.add(BOLD_SPAN_INFO);
}
// We first collect the link IDs into a set to allow multiple links with same ID.
Set<Integer> linkIds = new HashSet<>();
Matcher matcher = LINK_PATTERN.matcher(text);
while (matcher.find()) {
linkIds.add(Integer.parseInt(matcher.group(1)));
}
for (Integer linkId : linkIds) {
spans.add(new SpanApplier.SpanInfo("<link" + linkId + ">", "</link" + linkId + ">",
new NoUnderlineClickableSpan(view.getContext().getResources(), (unusedView) -> {
if (linkCallback != null) {
linkCallback.onResult(linkId);
}
})));
}
view.setText(SpanApplier.applySpans(
text, spans.toArray(new SpanApplier.SpanInfo[spans.size()])));
view.setMovementMethod(linkIds.isEmpty() ? null : LinkMovementMethod.getInstance());
}
}