| 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;
|
|
|