blob: 8203cbf8802a840bc9d8f5c92d450ff73e9a48e9 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "autocomplete_match_classification.h"
#include "base/i18n/case_conversion.h"
#include "base/strings/utf_string_conversions.h"
#include "components/omnibox/browser/scored_history_match.h"
#include "in_memory_url_index_types.h"
namespace {
base::string16 clean(base::string16 text) {
const size_t kMaxTextLength = 2000;
return base::i18n::ToLower(text.substr(0, kMaxTextLength));
}
} // namespace
TermMatches FindTermMatches(base::string16 find_text,
base::string16 text,
bool allow_prefix_matching,
bool allow_mid_word_matching) {
find_text = clean(find_text);
text = clean(text);
if (allow_prefix_matching &&
base::StartsWith(text, find_text, base::CompareCase::SENSITIVE))
return {{0, 0, find_text.length()}};
String16Vector find_terms =
String16VectorFromString16(find_text, false, NULL);
TermMatches matches = MatchTermsInString(find_terms, text);
matches = SortMatches(matches);
matches = DeoverlapMatches(matches);
if (allow_mid_word_matching)
return matches;
WordStarts word_starts;
String16VectorFromString16(text, false, &word_starts);
return ScoredHistoryMatch::FilterTermMatchesByWordStarts(
matches, WordStarts(find_terms.size(), 0), word_starts, 0,
std::string::npos);
}
ACMatchClassifications ClassifyTermMatches(TermMatches matches,
size_t text_length,
int match_style,
int non_match_style) {
ACMatchClassifications classes;
if (matches.empty()) {
if (text_length)
classes.push_back(ACMatchClassification(0, non_match_style));
return classes;
}
if (matches[0].offset)
classes.push_back(ACMatchClassification(0, non_match_style));
size_t match_count = matches.size();
for (size_t i = 0; i < match_count;) {
size_t offset = matches[i].offset;
classes.push_back(ACMatchClassification(offset, match_style));
// Skip all adjacent matches.
do {
offset += matches[i].length;
++i;
} while ((i < match_count) && (offset == matches[i].offset));
if (offset < text_length)
classes.push_back(ACMatchClassification(offset, non_match_style));
}
return classes;
}