Index: chrome/browser/history/query_parser.cc |
diff --git a/chrome/browser/history/query_parser.cc b/chrome/browser/history/query_parser.cc |
index 9fafc9bf1b29c3a189a2719e362ea38917ff58e5..6a436c24e224d60fc363527bb2dd8167e9946e7d 100644 |
--- a/chrome/browser/history/query_parser.cc |
+++ b/chrome/browser/history/query_parser.cc |
@@ -11,9 +11,14 @@ |
#include "base/i18n/case_conversion.h" |
#include "base/logging.h" |
#include "base/stl_util.h" |
+#include "base/strings/utf_string_conversions.h" |
namespace { |
+// Chinese/Japanese/Thai languages do not use spaces between words, so we |
+// allow any Chinese/Japanese/Thai character to match as a word boundary. |
+char kSafeRegexWordBoundary[] = "(\\b|[\\u0E00-\\u0E7F]|[\\u4E00-\\u9FFF])"; |
+ |
// Returns true if |mp1.first| is less than |mp2.first|. This is used to |
// sort match positions. |
int CompareMatchPosition(const Snippet::MatchPosition& mp1, |
@@ -83,6 +88,8 @@ class QueryNodeWord : public QueryNode { |
// QueryNode: |
virtual int AppendToSQLiteQuery(string16* query) const OVERRIDE; |
+ virtual void AppendSQLiteRegexpQueries( |
+ std::vector<string16>* queries) const OVERRIDE; |
virtual bool IsWord() const OVERRIDE; |
virtual bool Matches(const string16& word, bool exact) const OVERRIDE; |
virtual bool HasMatchIn( |
@@ -112,6 +119,19 @@ int QueryNodeWord::AppendToSQLiteQuery(string16* query) const { |
return 1; |
} |
+void QueryNodeWord::AppendSQLiteRegexpQueries( |
+ std::vector<string16>* queries) const { |
+ string16 query = ASCIIToUTF16("(?i).*"); |
+ query.append(ASCIIToUTF16(kSafeRegexWordBoundary)); |
+ query.append(word_); |
+ if (!literal_ && QueryParser::IsWordLongEnoughForPrefixSearch(word_)) |
+ query.append(ASCIIToUTF16("\\w*")); |
+ query.append(ASCIIToUTF16(kSafeRegexWordBoundary)); |
+ query.append(ASCIIToUTF16(".*")); |
+ |
+ queries->push_back(query); |
+} |
+ |
bool QueryNodeWord::IsWord() const { |
return true; |
} |
@@ -159,6 +179,8 @@ class QueryNodeList : public QueryNode { |
// QueryNode: |
virtual int AppendToSQLiteQuery(string16* query) const OVERRIDE; |
+ virtual void AppendSQLiteRegexpQueries( |
+ std::vector<string16>* queries) const OVERRIDE; |
virtual bool IsWord() const OVERRIDE; |
virtual bool Matches(const string16& word, bool exact) const OVERRIDE; |
virtual bool HasMatchIn( |
@@ -204,6 +226,14 @@ int QueryNodeList::AppendToSQLiteQuery(string16* query) const { |
return AppendChildrenToString(query); |
} |
+void QueryNodeList::AppendSQLiteRegexpQueries( |
+ std::vector<string16>* queries) const { |
+ for (QueryNodeVector::const_iterator node = children_.begin(); |
+ node != children_.end(); ++node) { |
+ (*node)->AppendSQLiteRegexpQueries(queries); |
+ } |
+} |
+ |
bool QueryNodeList::IsWord() const { |
return false; |
} |
@@ -243,6 +273,8 @@ class QueryNodePhrase : public QueryNodeList { |
// QueryNodeList: |
virtual int AppendToSQLiteQuery(string16* query) const OVERRIDE; |
+ virtual void AppendSQLiteRegexpQueries( |
+ std::vector<string16>* queries) const OVERRIDE; |
virtual bool HasMatchIn( |
const std::vector<QueryWord>& words, |
Snippet::MatchPositions* match_positions) const OVERRIDE; |
@@ -262,6 +294,23 @@ int QueryNodePhrase::AppendToSQLiteQuery(string16* query) const { |
return num_words; |
} |
+void QueryNodePhrase::AppendSQLiteRegexpQueries( |
+ std::vector<string16>* queries) const { |
+ string16 query = ASCIIToUTF16("(?i).*"); |
+ query.append(ASCIIToUTF16(kSafeRegexWordBoundary)); |
+ for (QueryNodeVector::const_iterator node = children_.begin(); |
+ node != children_.end(); ++node) { |
+ (*node)->AppendToSQLiteQuery(&query); |
+ if (node + 1 != children_.end()) { |
+ // Match any non-word characters within phrase (enables url matching). |
+ query.append(ASCIIToUTF16("\\W+")); |
+ } |
+ } |
+ query.append(ASCIIToUTF16(kSafeRegexWordBoundary)); |
+ query.append(ASCIIToUTF16(".*")); |
+ queries->push_back(query); |
+} |
+ |
bool QueryNodePhrase::HasMatchIn( |
const std::vector<QueryWord>& words, |
Snippet::MatchPositions* match_positions) const { |
@@ -308,6 +357,14 @@ int QueryParser::ParseQuery(const string16& query, string16* sqlite_query) { |
return root.AppendToSQLiteQuery(sqlite_query); |
} |
+void QueryParser::ParseQueryAsRegexps(const string16& query, |
+ std::vector<string16>* sqlite_queries) { |
+ QueryNodeList root; |
+ if (!ParseQueryImpl(query, &root)) |
+ return; |
+ return root.AppendSQLiteRegexpQueries(sqlite_queries); |
+} |
+ |
void QueryParser::ParseQueryWords(const string16& query, |
std::vector<string16>* words) { |
QueryNodeList root; |