Fix search highlight in multi-whitespace bodies.

The way the highlight was done could get screwed up if you had multiple
whitespaces in a row. This particularly came up with messages with
multiple newlines.
This commit is contained in:
Greyson Parrelli 2019-02-28 11:55:12 -08:00
parent 42e94d8f92
commit 7fd6f5b3ff
2 changed files with 27 additions and 11 deletions

View File

@ -61,25 +61,32 @@ public class SearchUtil {
@NonNull String text,
@NonNull String highlight)
{
if (text.length() == 0) {
return Collections.emptyList();
}
String normalizedText = text.toLowerCase(locale);
String normalizedHighlight = highlight.toLowerCase(locale);
List<String> highlightTokens = Stream.of(normalizedHighlight.split("\\s")).filter(s -> s.trim().length() > 0).toList();
List<String> textTokens = Stream.of(normalizedText.split("\\s")).filter(s -> s.trim().length() > 0).toList();
List<Pair<Integer, Integer>> ranges = new LinkedList<>();
int textListIndex = 0;
int textCharIndex = 0;
int lastHighlightEndIndex = 0;
for (String highlightToken : highlightTokens) {
for (int i = textListIndex; i < textTokens.size(); i++) {
if (textTokens.get(i).startsWith(highlightToken)) {
textListIndex = i + 1;
ranges.add(new Pair<>(textCharIndex, textCharIndex + highlightToken.length()));
textCharIndex += textTokens.get(i).length() + 1;
break;
}
textCharIndex += textTokens.get(i).length() + 1;
int index;
do {
index = normalizedText.indexOf(highlightToken, lastHighlightEndIndex);
lastHighlightEndIndex = index + highlightToken.length();
} while (index > 0 && !Character.isWhitespace(normalizedText.charAt(index - 1)));
if (index >= 0) {
ranges.add(new Pair<>(index, lastHighlightEndIndex));
}
if (index < 0 || lastHighlightEndIndex >= normalizedText.length()) {
break;
}
}

View File

@ -23,6 +23,15 @@ public class SearchUtilTest {
assertEquals(Arrays.asList(new Pair<>(0, 1)), result);
}
@Test
public void getHighlightRanges_singleHighlightTokenWithNewLines() {
String text = "123\n\n\nabc";
String highlight = "a";
List<Pair<Integer, Integer>> result = SearchUtil.getHighlightRanges(LOCALE, text, highlight);
assertEquals(Arrays.asList(new Pair<>(6, 7)), result);
}
@Test
public void getHighlightRanges_multipleHighlightTokens() {
String text = "a bc";