1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Use of this source code is governed by a BSD-style license that can be
3bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// found in the LICENSE file.
4bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
5bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/autocomplete/history_quick_provider.h"
6bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
7ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include <vector>
8ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
9731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/basictypes.h"
1021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "base/i18n/break_iterator.h"
11731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/logging.h"
12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/metrics/histogram.h"
13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/string_number_conversions.h"
14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/string_util.h"
15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/time.h"
16731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/utf_string_conversions.h"
17731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/browser/history/history.h"
18731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/browser/history/in_memory_url_index.h"
19731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/browser/net/url_fixer_upper.h"
20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/prefs/pref_service.h"
21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/profiles/profile.h"
22731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/common/pref_names.h"
23731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/common/url_constants.h"
24ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "googleurl/src/url_parse.h"
25ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_source.h"
26ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_type.h"
27731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "googleurl/src/url_util.h"
28731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "net/base/escape.h"
29731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "net/base/net_util.h"
30731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
31731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickusing history::InMemoryURLIndex;
32731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickusing history::ScoredHistoryMatch;
33731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickusing history::ScoredHistoryMatches;
34731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
35731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickHistoryQuickProvider::HistoryQuickProvider(ACProviderListener* listener,
36731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                           Profile* profile)
37731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    : HistoryProvider(listener, profile, "HistoryQuickProvider"),
38731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      languages_(profile_->GetPrefs()->GetString(prefs::kAcceptLanguages)) {}
39731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
40731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickHistoryQuickProvider::~HistoryQuickProvider() {}
41731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
42bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid HistoryQuickProvider::Start(const AutocompleteInput& input,
43bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                                 bool minimal_changes) {
44731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  matches_.clear();
45731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
46731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if ((input.type() == AutocompleteInput::INVALID) ||
47731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      (input.type() == AutocompleteInput::FORCED_QUERY))
48731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    return;
49731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
50731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  autocomplete_input_ = input;
51731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
52731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Do some fixup on the user input before matching against it, so we provide
53731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // good results for local file paths, input with spaces, etc.
54731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // NOTE: This purposefully doesn't take input.desired_tld() into account; if
55731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // it did, then holding "ctrl" would change all the results from the
56731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // HistoryQuickProvider provider, not just the What You Typed Result.
5772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  const string16 fixed_text(FixupUserInput(input));
58731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (fixed_text.empty()) {
59731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    // Conceivably fixup could result in an empty string (although I don't
60731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    // have cases where this happens offhand).  We can't do anything with
61731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    // empty input, so just bail; otherwise we'd crash later.
62731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    return;
63731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
64731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  autocomplete_input_.set_text(fixed_text);
65731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
66731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // TODO(pkasting): We should just block here until this loads.  Any time
67731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // someone unloads the history backend, we'll get inconsistent inline
68731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // autocomplete behavior here.
69731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (GetIndex()) {
70ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    base::TimeTicks start_time = base::TimeTicks::Now();
71731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    DoAutocomplete();
72ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (input.text().size() < 6) {
73ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      base::TimeTicks end_time = base::TimeTicks::Now();
74ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      std::string name = "HistoryQuickProvider.QueryIndexTime." +
75ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          base::IntToString(input.text().size());
76ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      base::Histogram* counter = base::Histogram::FactoryGet(
77ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          name, 1, 1000, 50, base::Histogram::kUmaTargetedHistogramFlag);
78ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      counter->Add(static_cast<int>((end_time - start_time).InMilliseconds()));
79ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
80731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    UpdateStarredStateOfMatches();
81731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
82731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
83731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
8421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// HistoryQuickProvider matches are currently not deletable.
8521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// TODO(mrossetti): Determine when a match should be deletable.
8621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid HistoryQuickProvider::DeleteMatch(const AutocompleteMatch& match) {}
8721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
88731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid HistoryQuickProvider::DoAutocomplete() {
89731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Get the matching URLs from the DB.
9072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  string16 term_string = autocomplete_input_.text();
91731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  term_string = UnescapeURLComponent(term_string,
92731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      UnescapeRule::SPACES | UnescapeRule::URL_SPECIAL_CHARS);
93731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  history::InMemoryURLIndex::String16Vector terms(
94ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      InMemoryURLIndex::WordVectorFromString16(term_string, false));
95731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ScoredHistoryMatches matches = GetIndex()->HistoryItemsForTerms(terms);
96ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (matches.empty())
97ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
98731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
99ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Artificially reduce the score of high-scoring results which should not be
100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // inline autocompletd. Each such result gets the next available
101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // |next_dont_inline_score|. Upon use of next_dont_inline_score it is
102ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // decremented.
103ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  int next_dont_inline_score = 1199;
104731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  size_t match_num = matches.size() - 1;
105731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  for (ScoredHistoryMatches::const_iterator match_iter = matches.begin();
106731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick       match_iter != matches.end(); ++match_iter, --match_num) {
107731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    const ScoredHistoryMatch& history_match(*match_iter);
108ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (history_match.raw_score > 0) {
109ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      AutocompleteMatch ac_match =
110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          QuickMatchToACMatch(history_match, match_num,
111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen              autocomplete_input_.prevent_inline_autocomplete(),
112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen              &next_dont_inline_score);
113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      matches_.push_back(ac_match);
114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
115731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
116731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
117731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
118731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickAutocompleteMatch HistoryQuickProvider::QuickMatchToACMatch(
119731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    const ScoredHistoryMatch& history_match,
120ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    size_t match_number,
121ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    bool prevent_inline_autocomplete,
122ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    int* next_dont_inline_score) {
123ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(next_dont_inline_score);
124731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  const history::URLRow& info = history_match.url_info;
125731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  int score = CalculateRelevance(history_match.raw_score,
126731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                 autocomplete_input_.type(),
127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                 NORMAL, match_number);
128ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
129ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Discount a very high score when a) a match doesn't start at the beginning
130ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // of the URL, or b) there are more than one substring matches in the URL, or
131ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // c) the type of request does not allow inline autocompletion. This prevents
132ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // the URL from being offered as an inline completion.
133ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  const int kMaxDontInlineScore = 1199;
134ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (score > kMaxDontInlineScore &&
135ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      (prevent_inline_autocomplete || history_match.url_matches.size() > 1 ||
136ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen       history_match.url_matches[0].offset > 0)) {
137ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    score = std::min(*next_dont_inline_score, score);
138ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    --*next_dont_inline_score;
139ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
140ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
141731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AutocompleteMatch match(this, score, !!info.visit_count(),
142ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                          history_match.url_matches.empty() ?
143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                          AutocompleteMatch::HISTORY_URL :
144ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                          AutocompleteMatch::HISTORY_TITLE);
145ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
146731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  match.destination_url = info.url();
147731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DCHECK(match.destination_url.is_valid());
148ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
149ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Format the fill_into_edit and determine its offset.
150731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  size_t inline_autocomplete_offset =
151731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      history_match.input_location + autocomplete_input_.text().length();
152731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  match.fill_into_edit =
153731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      AutocompleteInput::FormattedStringWithEquivalentMeaning(info.url(),
154ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          net::FormatUrl(info.url(), languages_, net::kFormatUrlOmitAll,
155ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          UnescapeRule::SPACES, NULL, NULL, &inline_autocomplete_offset));
156731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (!autocomplete_input_.prevent_inline_autocomplete())
157731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    match.inline_autocomplete_offset = inline_autocomplete_offset;
15872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DCHECK((match.inline_autocomplete_offset == string16::npos) ||
159731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick         (match.inline_autocomplete_offset <= match.fill_into_edit.length()));
160731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
161ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Format the URL autocomplete presentation.
162ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::vector<size_t> offsets =
163ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      InMemoryURLIndex::OffsetsFromTermMatches(history_match.url_matches);
164ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  match.contents =
165ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      net::FormatUrlWithOffsets(info.url(), languages_, net::kFormatUrlOmitAll,
166ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                UnescapeRule::SPACES, NULL, NULL, &offsets);
167ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  history::TermMatches new_matches =
168ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      InMemoryURLIndex::ReplaceOffsetsInTermMatches(history_match.url_matches,
169ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                                    offsets);
170ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  match.contents_class = SpansFromTermMatch(new_matches, match.contents.size());
171ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
172ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Format the description autocomplete presentation.
17372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  match.description = info.title();
174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  match.description_class = SpansFromTermMatch(history_match.title_matches,
175ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                               match.description.size());
176731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
177731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  return match;
178bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
179731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
180731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickhistory::InMemoryURLIndex* HistoryQuickProvider::GetIndex() {
181731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (index_for_testing_.get())
182731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    return index_for_testing_.get();
183731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
184731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  HistoryService* const history_service =
185731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
186731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (!history_service)
187731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    return NULL;
188731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
189731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  return history_service->InMemoryIndex();
190731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
191731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
192731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid HistoryQuickProvider::SetIndexForTesting(
193731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    history::InMemoryURLIndex* index) {
194731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DCHECK(index);
195731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  index_for_testing_.reset(index);
196731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
197731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
198731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// static
199731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickint HistoryQuickProvider::CalculateRelevance(int raw_score,
200731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                             AutocompleteInput::Type input_type,
201731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                             MatchType match_type,
202731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                             size_t match_number) {
203731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  switch (match_type) {
204731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    case INLINE_AUTOCOMPLETE:
205731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      return 1400;
206731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
207731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    case WHAT_YOU_TYPED:
208731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      return 1200;
209731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
210731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    default:
211ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return raw_score;
212731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
213731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
214ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
215ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// static
216ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenACMatchClassifications HistoryQuickProvider::SpansFromTermMatch(
217ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const history::TermMatches& matches,
218ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    size_t text_length) {
219ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ACMatchClassifications spans;
220ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (matches.empty()) {
221ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (text_length)
222ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      spans.push_back(ACMatchClassification(0, ACMatchClassification::DIM));
223ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return spans;
224ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
225ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (matches[0].offset)
226ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    spans.push_back(ACMatchClassification(0, ACMatchClassification::NONE));
227ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  size_t match_count = matches.size();
228ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  for (size_t i = 0; i < match_count;) {
229ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    size_t offset = matches[i].offset;
230ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    spans.push_back(ACMatchClassification(offset,
231ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                          ACMatchClassification::MATCH));
232ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Skip all adjacent matches.
233ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    do {
234ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      offset += matches[i].length;
235ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      ++i;
236ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } while ((i < match_count) && (offset == matches[i].offset));
237ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (offset < text_length) {
238ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      spans.push_back(ACMatchClassification(offset,
239ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                            ACMatchClassification::NONE));
240ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
241ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
242ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
243ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return spans;
244ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
245