Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(108)

Side by Side Diff: chrome/browser/chromeos/drive/search_metadata.cc

Issue 15945004: Case-insensitive search for non-ASCII characters in auto-complete of Drive files. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Review fix. Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/chromeos/drive/search_metadata.h" 5 #include "chrome/browser/chromeos/drive/search_metadata.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <queue> 8 #include <queue>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/string_util.h" 11 #include "base/i18n/string_search.h"
12 #include "base/strings/utf_string_conversions.h"
12 #include "chrome/browser/chromeos/drive/file_cache.h" 13 #include "chrome/browser/chromeos/drive/file_cache.h"
13 #include "chrome/browser/chromeos/drive/file_system_util.h" 14 #include "chrome/browser/chromeos/drive/file_system_util.h"
14 #include "content/public/browser/browser_thread.h" 15 #include "content/public/browser/browser_thread.h"
15 #include "net/base/escape.h" 16 #include "net/base/escape.h"
16 17
17 using content::BrowserThread; 18 using content::BrowserThread;
18 19
19 namespace drive { 20 namespace drive {
20 namespace internal { 21 namespace internal {
21 22
22 namespace { 23 namespace {
23 24
24 // Used to sort the result canididates per the last accessed/modified time. The 25 // Used to sort the result candidates per the last accessed/modified time. The
25 // recently accessed/modified files come first. 26 // recently accessed/modified files come first.
26 bool CompareByTimestamp(const ResourceEntry& a, const ResourceEntry& b) { 27 bool CompareByTimestamp(const ResourceEntry& a, const ResourceEntry& b) {
27 const PlatformFileInfoProto& a_file_info = a.file_info(); 28 const PlatformFileInfoProto& a_file_info = a.file_info();
28 const PlatformFileInfoProto& b_file_info = b.file_info(); 29 const PlatformFileInfoProto& b_file_info = b.file_info();
29 30
30 if (a_file_info.last_accessed() != b_file_info.last_accessed()) 31 if (a_file_info.last_accessed() != b_file_info.last_accessed())
31 return a_file_info.last_accessed() > b_file_info.last_accessed(); 32 return a_file_info.last_accessed() > b_file_info.last_accessed();
32 33
33 // When the entries have the same last access time (which happens quite often 34 // When the entries have the same last access time (which happens quite often
34 // because Drive server doesn't set the field until an entry is viewed via 35 // because Drive server doesn't set the field until an entry is viewed via
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 const std::string& query, 123 const std::string& query,
123 int options, 124 int options,
124 size_t at_most_num_matches, 125 size_t at_most_num_matches,
125 ScopedPriorityQueue<MetadataSearchResult, 126 ScopedPriorityQueue<MetadataSearchResult,
126 MetadataSearchResultComparator>* result_candidates, 127 MetadataSearchResultComparator>* result_candidates,
127 const ResourceEntry& entry) { 128 const ResourceEntry& entry) {
128 DCHECK_GE(at_most_num_matches, result_candidates->size()); 129 DCHECK_GE(at_most_num_matches, result_candidates->size());
129 130
130 // Add |entry| to the result if the entry is eligible for the given 131 // Add |entry| to the result if the entry is eligible for the given
131 // |options| and matches the query. The base name of the entry must 132 // |options| and matches the query. The base name of the entry must
132 // contains |query| to match the query. 133 // contain |query| to match the query.
133 std::string highlighted; 134 std::string highlighted;
134 if (!IsEligibleEntry(entry, cache, options) || 135 if (!IsEligibleEntry(entry, cache, options) ||
135 !FindAndHighlight(entry.base_name(), query, &highlighted)) 136 !FindAndHighlight(entry.base_name(), query, &highlighted))
136 return; 137 return;
137 138
138 base::FilePath path = resource_metadata->GetFilePath(entry.resource_id()); 139 base::FilePath path = resource_metadata->GetFilePath(entry.resource_id());
139 if (path.empty()) 140 if (path.empty())
140 return; 141 return;
141 142
142 // Make space for |entry| when appropriate. 143 // Make space for |entry| when appropriate.
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 bool FindAndHighlight(const std::string& text, 210 bool FindAndHighlight(const std::string& text,
210 const std::string& query, 211 const std::string& query,
211 std::string* highlighted_text) { 212 std::string* highlighted_text) {
212 DCHECK(highlighted_text); 213 DCHECK(highlighted_text);
213 highlighted_text->clear(); 214 highlighted_text->clear();
214 215
215 // For empty query, any filename matches with no highlighted text. 216 // For empty query, any filename matches with no highlighted text.
216 if (query.empty()) 217 if (query.empty())
217 return true; 218 return true;
218 219
219 // TODO(satorux): Should support non-ASCII characters. 220 string16 text16 = base::UTF8ToUTF16(text);
220 std::string lower_text = StringToLowerASCII(text); 221 string16 query16 = base::UTF8ToUTF16(query);
221 std::string lower_query = StringToLowerASCII(query); 222 size_t match_start = 0;
222 223 size_t match_length = 0;
223 int num_matches = 0; 224 if (!base::i18n::StringSearchIgnoringCaseAndAccents(
224 std::string::size_type cursor = 0; 225 query16, text16, &match_start, &match_length)) {
225 226 return false;
226 while (cursor < text.size()) {
227 std::string::size_type matched_position =
228 lower_text.find(lower_query, cursor);
229 if (matched_position == std::string::npos)
230 break;
231 ++num_matches;
232
233 std::string skipped_piece =
234 net::EscapeForHTML(text.substr(cursor, matched_position - cursor));
235 std::string matched_piece =
236 net::EscapeForHTML(text.substr(matched_position, query.size()));
237
238 highlighted_text->append(skipped_piece);
239 highlighted_text->append("<b>" + matched_piece + "</b>");
240
241 cursor = matched_position + query.size();
242 } 227 }
243 if (num_matches == 0) 228 string16 pre = text16.substr(0, match_start);
244 return false; 229 string16 match = text16.substr(match_start, match_length);
245 230 string16 post = text16.substr(match_start + match_length);
246 std::string remaining_piece = text.substr(cursor); 231 highlighted_text->append(net::EscapeForHTML(UTF16ToUTF8(pre)));
247 highlighted_text->append(net::EscapeForHTML(remaining_piece)); 232 highlighted_text->append("<b>");
248 233 highlighted_text->append(net::EscapeForHTML(UTF16ToUTF8(match)));
234 highlighted_text->append("</b>");
235 highlighted_text->append(net::EscapeForHTML(UTF16ToUTF8(post)));
249 return true; 236 return true;
250 } 237 }
251 238
252 } // namespace internal 239 } // namespace internal
253 } // namespace drive 240 } // namespace drive
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/drive/search_metadata.h ('k') | chrome/browser/chromeos/drive/search_metadata_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698