search_metadata.cc 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  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
  3. // found in the LICENSE file.
  4. #include "components/drive/chromeos/search_metadata.h"
  5. #include <algorithm>
  6. #include "base/i18n/string_search.h"
  7. #include "base/strings/escape.h"
  8. #include "base/strings/string_util.h"
  9. #include "base/strings/utf_string_conversions.h"
  10. #include "base/time/time.h"
  11. #include "components/drive/drive_api_util.h"
  12. #include "components/drive/file_system_core_util.h"
  13. namespace drive {
  14. namespace internal {
  15. namespace {
  16. // Appends substring of |original_text| to |highlighted_text| with highlight.
  17. void AppendStringWithHighlight(const std::u16string& original_text,
  18. size_t start,
  19. size_t length,
  20. bool highlight,
  21. std::string* highlighted_text) {
  22. if (highlight)
  23. highlighted_text->append("<b>");
  24. highlighted_text->append(base::EscapeForHTML(
  25. base::UTF16ToUTF8(original_text.substr(start, length))));
  26. if (highlight)
  27. highlighted_text->append("</b>");
  28. }
  29. } // namespace
  30. bool FindAndHighlight(
  31. const std::string& text,
  32. const std::vector<std::unique_ptr<
  33. base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents>>& queries,
  34. std::string* highlighted_text) {
  35. DCHECK(highlighted_text);
  36. highlighted_text->clear();
  37. // Check text matches with all queries.
  38. size_t match_start = 0;
  39. size_t match_length = 0;
  40. std::u16string text16 = base::UTF8ToUTF16(text);
  41. std::vector<bool> highlights(text16.size(), false);
  42. for (const auto& query : queries) {
  43. if (!query->Search(text16, &match_start, &match_length))
  44. return false;
  45. std::fill(highlights.begin() + match_start,
  46. highlights.begin() + match_start + match_length, true);
  47. }
  48. // Generate highlighted text.
  49. size_t start_current_segment = 0;
  50. for (size_t i = 0; i < text16.size(); ++i) {
  51. if (highlights[start_current_segment] == highlights[i])
  52. continue;
  53. AppendStringWithHighlight(
  54. text16, start_current_segment, i - start_current_segment,
  55. highlights[start_current_segment], highlighted_text);
  56. start_current_segment = i;
  57. }
  58. DCHECK_GE(text16.size(), start_current_segment);
  59. AppendStringWithHighlight(
  60. text16, start_current_segment, text16.size() - start_current_segment,
  61. highlights[start_current_segment], highlighted_text);
  62. return true;
  63. }
  64. } // namespace internal
  65. } // namespace drive