Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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, match_length; |
|
satorux1
2013/05/27 05:00:24
nit: initialize them with 0 to be extra defensive.
kinaba
2013/05/27 05:50:26
Done.
| |
| 222 | 223 if (!base::i18n::StringSearchIgnoringCaseAndAccents( |
| 223 int num_matches = 0; | 224 query16, text16, &match_start, &match_length)) { |
| 224 std::string::size_type cursor = 0; | 225 return false; |
| 225 | |
| 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 } | 226 } |
| 243 if (num_matches == 0) | 227 string16 pre = text16.substr(0, match_start); |
| 244 return false; | 228 string16 match = text16.substr(match_start, match_length); |
| 245 | 229 string16 post = text16.substr(match_start + match_length); |
| 246 std::string remaining_piece = text.substr(cursor); | 230 highlighted_text->append(net::EscapeForHTML(UTF16ToUTF8(pre))); |
| 247 highlighted_text->append(net::EscapeForHTML(remaining_piece)); | 231 highlighted_text->append("<b>"); |
| 248 | 232 highlighted_text->append(net::EscapeForHTML(UTF16ToUTF8(match))); |
| 233 highlighted_text->append("</b>"); | |
| 234 highlighted_text->append(net::EscapeForHTML(UTF16ToUTF8(post))); | |
| 249 return true; | 235 return true; |
| 250 } | 236 } |
| 251 | 237 |
| 252 } // namespace internal | 238 } // namespace internal |
| 253 } // namespace drive | 239 } // namespace drive |
| OLD | NEW |