Revision: 8904
Author: [email protected]
Date: Thu Sep 30 08:46:04 2010
Log: Display all suggestions with query words bolded rather than just the
full query.
Addresses bug 3040137
Review at http://gwt-code-reviews.appspot.com/937801
Review by: [email protected]
http://code.google.com/p/google-web-toolkit/source/detail?r=8904
Modified:
/trunk/user/src/com/google/gwt/user/client/ui/MultiWordSuggestOracle.java
/trunk/user/test/com/google/gwt/user/client/ui/SuggestBoxTest.java
=======================================
---
/trunk/user/src/com/google/gwt/user/client/ui/MultiWordSuggestOracle.java
Thu Sep 16 08:59:16 2010
+++
/trunk/user/src/com/google/gwt/user/client/ui/MultiWordSuggestOracle.java
Thu Sep 30 08:46:04 2010
@@ -96,6 +96,35 @@
}
}
+ /**
+ * A class reresenting the bounds of a word within a string.
+ *
+ * The bounds are represented by a {...@code startIndex} (inclusive) and
+ * an {...@code endIndex} (exclusive).
+ */
+ private static class WordBounds implements Comparable<WordBounds> {
+
+ final int startIndex;
+ final int endIndex;
+
+ public WordBounds(int startIndex, int length) {
+ this.startIndex = startIndex;
+ this.endIndex = startIndex + length;
+ }
+
+ public int compareTo(WordBounds that) {
+ int comparison = this.startIndex - that.startIndex;
+ if (comparison == 0) {
+ comparison = that.endIndex - this.endIndex;
+ }
+ return comparison;
+ }
+
+ public int length() {
+ return endIndex - startIndex;
+ }
+ }
+
private static final char WHITESPACE_CHAR = ' ';
private static final String WHITESPACE_STRING = " ";
@@ -300,37 +329,37 @@
for (int i = 0; i < candidates.size(); i++) {
String candidate = candidates.get(i);
- int index = 0;
int cursor = 0;
+ int index = 0;
// Use real suggestion for assembly.
String formattedSuggestion = toRealSuggestions.get(candidate);
// Create strong search string.
StringBuffer accum = new StringBuffer();
-
+
+ String[] searchWords = query.split(WHITESPACE_STRING);
while (true) {
- index = candidate.indexOf(query, index);
- if (index == -1) {
+ WordBounds wordBounds = findNextWord(candidate, searchWords,
index);
+ if (wordBounds == null) {
break;
}
- int endIndex = index + query.length();
- if (index == 0 || (WHITESPACE_CHAR == candidate.charAt(index -
1))) {
- String part1 = escapeText(formattedSuggestion.substring(cursor,
index));
- String part2 = escapeText(formattedSuggestion.substring(index,
- endIndex));
- cursor = endIndex;
+ if (wordBounds.startIndex == 0 ||
+ WHITESPACE_CHAR == candidate.charAt(wordBounds.startIndex -
1)) {
+ String part1 = escapeText(formattedSuggestion.substring(cursor,
wordBounds.startIndex));
+ String part2 =
escapeText(formattedSuggestion.substring(wordBounds.startIndex,
+ wordBounds.endIndex));
+ cursor = wordBounds.endIndex;
accum.append(part1).append("<strong>").append(part2).append(
"</strong>");
}
- index = endIndex;
- }
-
+ index = wordBounds.endIndex;
+ }
+
// Check to make sure the search was found in the string.
if (cursor == 0) {
continue;
}
-
- // Finish creating the formatted string.
+
String end = escapeText(formattedSuggestion.substring(cursor));
accum.append(end);
MultiWordSuggestion suggestion =
createSuggestion(formattedSuggestion,
@@ -405,7 +434,26 @@
}
return candidateSet;
}
-
+
+ /**
+ * @return a {...@link WordBounds} representing the first word in
+ * {...@code searchWords} that is found in candidate starting at
+ * {...@code indexToStartAt} or {...@code null} if no words could be
found.
+ */
+ private WordBounds findNextWord(String candidate, String[] searchWords,
int indexToStartAt) {
+ WordBounds firstWord = null;
+ for (String word : searchWords) {
+ int index = candidate.indexOf(word, indexToStartAt);
+ if (index != -1) {
+ WordBounds newWord = new WordBounds(index, word.length());
+ if (firstWord == null || newWord.compareTo(firstWord) < 0) {
+ firstWord = newWord;
+ }
+ }
+ }
+ return firstWord;
+ }
+
/**
* Normalize the search key by making it lower case, removing multiple
spaces,
* apply whitespace masks, and make it lower case.
=======================================
--- /trunk/user/test/com/google/gwt/user/client/ui/SuggestBoxTest.java Mon
Mar 29 09:42:22 2010
+++ /trunk/user/test/com/google/gwt/user/client/ui/SuggestBoxTest.java Thu
Sep 30 08:46:04 2010
@@ -127,6 +127,43 @@
box.showSuggestionList();
}
+ public void testLargerMatchShows() {
+ MultiWordSuggestOracle oracle = new MultiWordSuggestOracle(" ");
+ oracle.add("He'll help me wont he");
+
+ TestSuggestionDisplay display = new TestSuggestionDisplay();
+ SuggestBox box = new SuggestBox(oracle, new TextBox(), display);
+ RootPanel.get().add(box);
+ box.setText("He help");
+ box.showSuggestionList();
+ assertTrue(display.isSuggestionListShowing());
+ assertEquals(1, display.getSuggestionCount());
+ assertEquals("<strong>he</strong>'ll <strong>help</strong> me wont
<strong>he</strong>",
+ display.getSuggestion(0).getDisplayString().toLowerCase());
+ }
+
+ public void testMultipleWordMatchesShow() {
+ MultiWordSuggestOracle oracle = new MultiWordSuggestOracle(",! ");
+ oracle.add("Hark, Shark and Herald");
+ oracle.add("Hark! The Herald Angels Sing");
+ oracle.add("Heraldings and Harkings");
+ oracle.add("Send my regards to Herald");
+
+ TestSuggestionDisplay display = new TestSuggestionDisplay();
+ SuggestBox box = new SuggestBox(oracle, new TextBox(), display);
+ RootPanel.get().add(box);
+ box.setText("Herald! Hark");
+ box.showSuggestionList();
+ assertTrue(display.isSuggestionListShowing());
+ assertEquals(3, display.getSuggestionCount());
+ assertEquals("<strong>hark</strong>, shark and
<strong>herald</strong>",
+ display.getSuggestion(0).getDisplayString().toLowerCase());
+ assertEquals("<strong>hark</strong>! the <strong>herald</strong>
angels sing",
+ display.getSuggestion(1).getDisplayString().toLowerCase());
+ assertEquals("<strong>herald</strong>ings and
<strong>hark</strong>ings",
+ display.getSuggestion(2).getDisplayString().toLowerCase());
+ }
+
@SuppressWarnings("deprecation")
public void testShowAndHide() {
SuggestBox box = createSuggestBox();
--
http://groups.google.com/group/Google-Web-Toolkit-Contributors