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

Side by Side Diff: chrome/browser/autocomplete/bookmark_provider.cc

Issue 184663002: Omnibox: Make URLs of Bookmarks Searchable (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix ALL_MATCHES (in response to recent changes) Created 6 years, 8 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/autocomplete/bookmark_provider.h" 5 #include "chrome/browser/autocomplete/bookmark_provider.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <functional> 8 #include <functional>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/prefs/pref_service.h" 11 #include "base/prefs/pref_service.h"
12 #include "base/strings/utf_string_conversions.h" 12 #include "base/strings/utf_string_conversions.h"
13 #include "chrome/browser/autocomplete/autocomplete_result.h" 13 #include "chrome/browser/autocomplete/autocomplete_result.h"
14 #include "chrome/browser/autocomplete/history_provider.h" 14 #include "chrome/browser/autocomplete/history_provider.h"
15 #include "chrome/browser/autocomplete/url_prefix.h" 15 #include "chrome/browser/autocomplete/url_prefix.h"
16 #include "chrome/browser/bookmarks/bookmark_model.h" 16 #include "chrome/browser/bookmarks/bookmark_model.h"
17 #include "chrome/browser/bookmarks/bookmark_model_factory.h" 17 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
18 #include "chrome/browser/omnibox/omnibox_field_trial.h"
18 #include "chrome/browser/profiles/profile.h" 19 #include "chrome/browser/profiles/profile.h"
19 #include "chrome/common/pref_names.h" 20 #include "chrome/common/pref_names.h"
20 #include "components/bookmarks/core/browser/bookmark_title_match.h" 21 #include "components/bookmarks/core/browser/bookmark_match.h"
21 #include "net/base/net_util.h" 22 #include "net/base/net_util.h"
22 23
23 typedef std::vector<BookmarkTitleMatch> TitleMatches; 24 typedef std::vector<BookmarkMatch> BookmarkMatches;
24 25
25 // BookmarkProvider ------------------------------------------------------------ 26 // BookmarkProvider ------------------------------------------------------------
26 27
27 BookmarkProvider::BookmarkProvider( 28 BookmarkProvider::BookmarkProvider(
28 AutocompleteProviderListener* listener, 29 AutocompleteProviderListener* listener,
29 Profile* profile) 30 Profile* profile)
30 : AutocompleteProvider(listener, profile, 31 : AutocompleteProvider(listener, profile,
31 AutocompleteProvider::TYPE_BOOKMARK), 32 AutocompleteProvider::TYPE_BOOKMARK),
32 bookmark_model_(NULL) { 33 bookmark_model_(NULL),
34 score_using_url_matches_(OmniboxFieldTrial::BookmarksIndexURLsValue()) {
33 if (profile) { 35 if (profile) {
34 bookmark_model_ = BookmarkModelFactory::GetForProfile(profile); 36 bookmark_model_ = BookmarkModelFactory::GetForProfile(profile);
35 languages_ = profile_->GetPrefs()->GetString(prefs::kAcceptLanguages); 37 languages_ = profile_->GetPrefs()->GetString(prefs::kAcceptLanguages);
36 } 38 }
37 } 39 }
38 40
39 void BookmarkProvider::Start(const AutocompleteInput& input, 41 void BookmarkProvider::Start(const AutocompleteInput& input,
40 bool minimal_changes) { 42 bool minimal_changes) {
41 if (minimal_changes) 43 if (minimal_changes)
42 return; 44 return;
43 matches_.clear(); 45 matches_.clear();
44 46
45 if (input.text().empty() || 47 if (input.text().empty() ||
46 ((input.type() != AutocompleteInput::UNKNOWN) && 48 (input.type() == AutocompleteInput::FORCED_QUERY))
47 (input.type() != AutocompleteInput::QUERY)))
48 return; 49 return;
49 50
50 DoAutocomplete(input); 51 DoAutocomplete(input);
51 } 52 }
52 53
53 BookmarkProvider::~BookmarkProvider() {} 54 BookmarkProvider::~BookmarkProvider() {}
54 55
55 void BookmarkProvider::DoAutocomplete(const AutocompleteInput& input) { 56 void BookmarkProvider::DoAutocomplete(const AutocompleteInput& input) {
56 // We may not have a bookmark model for some unit tests. 57 // We may not have a bookmark model for some unit tests.
57 if (!bookmark_model_) 58 if (!bookmark_model_)
58 return; 59 return;
59 60
60 TitleMatches matches; 61 BookmarkMatches matches;
61 // Retrieve enough bookmarks so that we have a reasonable probability of 62 // Retrieve enough bookmarks so that we have a reasonable probability of
62 // suggesting the one that the user desires. 63 // suggesting the one that the user desires.
63 const size_t kMaxBookmarkMatches = 50; 64 const size_t kMaxBookmarkMatches = 50;
64 65
65 // GetBookmarksWithTitlesMatching returns bookmarks matching the user's 66 // GetBookmarksMatching returns bookmarks matching the user's
66 // search terms using the following rules: 67 // search terms using the following rules:
67 // - The search text is broken up into search terms. Each term is searched 68 // - The search text is broken up into search terms. Each term is searched
68 // for separately. 69 // for separately.
69 // - Term matches are always performed against the start of a word. 'def' 70 // - Term matches are always performed against the start of a word. 'def'
70 // will match against 'define' but not against 'indefinite'. 71 // will match against 'define' but not against 'indefinite'.
71 // - Terms must be at least three characters in length in order to perform 72 // - Terms must be at least three characters in length in order to perform
72 // partial word matches. Any term of lesser length will only be used as an 73 // partial word matches. Any term of lesser length will only be used as an
73 // exact match. 'def' will match against 'define' but 'de' will not match. 74 // exact match. 'def' will match against 'define' but 'de' will not match.
74 // - A search containing multiple terms will return results with those words 75 // - A search containing multiple terms will return results with those words
75 // occuring in any order. 76 // occuring in any order.
76 // - Terms enclosed in quotes comprises a phrase that must match exactly. 77 // - Terms enclosed in quotes comprises a phrase that must match exactly.
77 // - Multiple terms enclosed in quotes will require those exact words in that 78 // - Multiple terms enclosed in quotes will require those exact words in that
78 // exact order to match. 79 // exact order to match.
79 // 80 //
80 // Note: GetBookmarksWithTitlesMatching() will never return a match span 81 // Please refer to the code for BookmarkIndex::GetBookmarksMatching for
81 // greater than the length of the title against which it is being matched, 82 // complete details of how searches are performed against the user's
82 // nor can those spans ever overlap because the match spans are coalesced
83 // for all matched terms.
84 //
85 // Please refer to the code for BookmarkIndex::GetBookmarksWithTitlesMatching
86 // for complete details of how title searches are performed against the user's
87 // bookmarks. 83 // bookmarks.
88 bookmark_model_->GetBookmarksWithTitlesMatching(input.text(), 84 bookmark_model_->GetBookmarksMatching(input.text(),
89 kMaxBookmarkMatches, 85 kMaxBookmarkMatches,
90 &matches); 86 &matches);
91 if (matches.empty()) 87 if (matches.empty())
92 return; // There were no matches. 88 return; // There were no matches.
93 AutocompleteInput fixed_up_input(input); 89 AutocompleteInput fixed_up_input(input);
94 FixupUserInput(&fixed_up_input); 90 FixupUserInput(&fixed_up_input);
95 for (TitleMatches::const_iterator i = matches.begin(); i != matches.end(); 91 for (BookmarkMatches::const_iterator i = matches.begin(); i != matches.end();
96 ++i) { 92 ++i) {
97 // Create and score the AutocompleteMatch. If its score is 0 then the 93 // Create and score the AutocompleteMatch. If its score is 0 then the
98 // match is discarded. 94 // match is discarded.
99 AutocompleteMatch match(TitleMatchToACMatch(input, fixed_up_input, *i)); 95 AutocompleteMatch match(BookmarkMatchToACMatch(input, fixed_up_input, *i));
100 if (match.relevance > 0) 96 if (match.relevance > 0)
101 matches_.push_back(match); 97 matches_.push_back(match);
102 } 98 }
103 99
104 // Sort and clip the resulting matches. 100 // Sort and clip the resulting matches.
105 size_t num_matches = 101 size_t num_matches =
106 std::min(matches_.size(), AutocompleteProvider::kMaxMatches); 102 std::min(matches_.size(), AutocompleteProvider::kMaxMatches);
107 std::partial_sort(matches_.begin(), matches_.begin() + num_matches, 103 std::partial_sort(matches_.begin(), matches_.begin() + num_matches,
108 matches_.end(), AutocompleteMatch::MoreRelevant); 104 matches_.end(), AutocompleteMatch::MoreRelevant);
109 matches_.resize(num_matches); 105 matches_.resize(num_matches);
110 } 106 }
111 107
112 namespace { 108 namespace {
113 109
114 // for_each helper functor that calculates a match factor for each query term 110 // for_each helper functor that calculates a match factor for each query term
115 // when calculating the final score. 111 // when calculating the final score.
116 // 112 //
117 // Calculate a 'factor' from 0.0 to 1.0 based on 1) how much of the bookmark's 113 // Calculate a 'factor' from 0 to the bookmark's title length for a match
118 // title the term matches, and 2) where the match is positioned within the 114 // based on 1) how many characters match and 2) where the match is positioned.
119 // bookmark's title. A full length match earns a 1.0. A half-length match earns
120 // at most a 0.5 and at least a 0.25. A single character match against a title
121 // that is 100 characters long where the match is at the first character will
122 // earn a 0.01 and at the last character will earn a 0.0001.
123 class ScoringFunctor { 115 class ScoringFunctor {
124 public: 116 public:
125 // |title_length| is the length of the bookmark title against which this 117 // |title_length| is the length of the bookmark title against which this
126 // match will be scored. 118 // match will be scored.
127 explicit ScoringFunctor(size_t title_length) 119 explicit ScoringFunctor(size_t title_length)
128 : title_length_(static_cast<double>(title_length)), 120 : title_length_(static_cast<double>(title_length)),
129 scoring_factor_(0.0) { 121 scoring_factor_(0.0) {
130 } 122 }
131 123
132 void operator()(const query_parser::Snippet::MatchPosition& match) { 124 void operator()(const query_parser::Snippet::MatchPosition& match) {
133 double term_length = static_cast<double>(match.second - match.first); 125 double term_length = static_cast<double>(match.second - match.first);
134 scoring_factor_ += term_length / title_length_ * 126 scoring_factor_ += term_length *
135 (title_length_ - match.first) / title_length_; 127 (title_length_ - match.first) / title_length_;
136 } 128 }
137 129
138 double ScoringFactor() { return scoring_factor_; } 130 double ScoringFactor() { return scoring_factor_; }
139 131
140 private: 132 private:
141 double title_length_; 133 double title_length_;
142 double scoring_factor_; 134 double scoring_factor_;
143 }; 135 };
144 136
145 } // namespace 137 } // namespace
146 138
147 AutocompleteMatch BookmarkProvider::TitleMatchToACMatch( 139 AutocompleteMatch BookmarkProvider::BookmarkMatchToACMatch(
148 const AutocompleteInput& input, 140 const AutocompleteInput& input,
149 const AutocompleteInput& fixed_up_input, 141 const AutocompleteInput& fixed_up_input,
150 const BookmarkTitleMatch& title_match) { 142 const BookmarkMatch& bookmark_match) {
151 // The AutocompleteMatch we construct is non-deletable because the only 143 // The AutocompleteMatch we construct is non-deletable because the only
152 // way to support this would be to delete the underlying bookmark, which is 144 // way to support this would be to delete the underlying bookmark, which is
153 // unlikely to be what the user intends. 145 // unlikely to be what the user intends.
154 AutocompleteMatch match(this, 0, false, 146 AutocompleteMatch match(this, 0, false,
155 AutocompleteMatchType::BOOKMARK_TITLE); 147 AutocompleteMatchType::BOOKMARK_TITLE);
156 const base::string16& title(title_match.node->GetTitle()); 148 base::string16 title(bookmark_match.node->GetTitle());
157 DCHECK(!title.empty()); 149 const GURL& url(bookmark_match.node->url());
158
159 const GURL& url(title_match.node->url());
160 const base::string16& url_utf16 = base::UTF8ToUTF16(url.spec()); 150 const base::string16& url_utf16 = base::UTF8ToUTF16(url.spec());
161 size_t match_start, inline_autocomplete_offset; 151 size_t inline_autocomplete_offset = URLPrefix::GetInlineAutocompleteOffset(
162 URLPrefix::ComputeMatchStartAndInlineAutocompleteOffset( 152 input, fixed_up_input, false, url_utf16);
163 input, fixed_up_input, false, url_utf16, &match_start,
164 &inline_autocomplete_offset);
165 match.destination_url = url; 153 match.destination_url = url;
154 const size_t match_start = bookmark_match.url_match_positions.empty() ?
155 0 : bookmark_match.url_match_positions[0].first;
166 const bool trim_http = !AutocompleteInput::HasHTTPScheme(input.text()) && 156 const bool trim_http = !AutocompleteInput::HasHTTPScheme(input.text()) &&
167 ((match_start == base::string16::npos) || (match_start != 0)); 157 ((match_start == base::string16::npos) || (match_start != 0));
168 match.contents = net::FormatUrl(url, languages_, 158 std::vector<size_t> offsets = BookmarkMatch::OffsetsFromMatchPositions(
159 bookmark_match.url_match_positions);
160 // In addition to knowing how |offsets| is transformed, we need to know how
161 // |inline_autocomplete_offset| is transformed. We add it to the end of
162 // |offsets|, compute how everything is transformed, then remove it from the
163 // end.
164 offsets.push_back(inline_autocomplete_offset);
165 match.contents = net::FormatUrlWithOffsets(url, languages_,
169 net::kFormatUrlOmitAll & ~(trim_http ? 0 : net::kFormatUrlOmitHTTP), 166 net::kFormatUrlOmitAll & ~(trim_http ? 0 : net::kFormatUrlOmitHTTP),
170 net::UnescapeRule::SPACES, NULL, NULL, &inline_autocomplete_offset); 167 net::UnescapeRule::SPACES, NULL, NULL, &offsets);
171 match.contents_class.push_back( 168 inline_autocomplete_offset = offsets.back();
172 ACMatchClassification(0, ACMatchClassification::URL)); 169 offsets.pop_back();
170 BookmarkMatch::MatchPositions new_url_match_positions =
171 BookmarkMatch::ReplaceOffsetsInMatchPositions(
172 bookmark_match.url_match_positions, offsets);
173 match.contents_class =
174 ClassificationsFromMatch(new_url_match_positions,
175 match.contents.size(),
176 true);
173 match.fill_into_edit = 177 match.fill_into_edit =
174 AutocompleteInput::FormattedStringWithEquivalentMeaning(url, 178 AutocompleteInput::FormattedStringWithEquivalentMeaning(url,
175 match.contents); 179 match.contents);
176 if (inline_autocomplete_offset != base::string16::npos) { 180 if (inline_autocomplete_offset != base::string16::npos) {
177 // |inline_autocomplete_offset| may be beyond the end of the 181 // |inline_autocomplete_offset| may be beyond the end of the
178 // |fill_into_edit| if the user has typed an URL with a scheme and the 182 // |fill_into_edit| if the user has typed an URL with a scheme and the
179 // last character typed is a slash. That slash is removed by the 183 // last character typed is a slash. That slash is removed by the
180 // FormatURLWithOffsets call above. 184 // FormatURLWithOffsets call above.
181 if (inline_autocomplete_offset < match.fill_into_edit.length()) { 185 if (inline_autocomplete_offset < match.fill_into_edit.length()) {
182 match.inline_autocompletion = 186 match.inline_autocompletion =
183 match.fill_into_edit.substr(inline_autocomplete_offset); 187 match.fill_into_edit.substr(inline_autocomplete_offset);
184 } 188 }
185 match.allowed_to_be_default_match = match.inline_autocompletion.empty() || 189 match.allowed_to_be_default_match = match.inline_autocompletion.empty() ||
186 !HistoryProvider::PreventInlineAutocomplete(input); 190 !HistoryProvider::PreventInlineAutocomplete(input);
187 } 191 }
188 match.description = title; 192 match.description = title;
189 match.description_class = 193 match.description_class =
190 ClassificationsFromMatch(title_match.match_positions, 194 ClassificationsFromMatch(bookmark_match.title_match_positions,
191 match.description.size()); 195 match.description.size(),
196 false);
192 match.starred = true; 197 match.starred = true;
193 198
194 // Summary on how a relevance score is determined for the match: 199 // Summary on how a relevance score is determined for the match:
195 // 200 //
196 // For each term matching within the bookmark's title (as given by the set of 201 // For each match within the bookmark's title or URL (or both), calculate a
197 // Snippet::MatchPositions) calculate a 'factor', sum up those factors, then 202 // 'factor', sum up those factors, then use the sum to figure out a value
198 // use the sum to figure out a value between the base score and the maximum 203 // between the base score and the maximum score.
199 // score.
200 // 204 //
201 // The factor for each term is the product of: 205 // The factor for each match is the product of:
202 // 206 //
203 // 1) how much of the bookmark's title has been matched by the term: 207 // 1) how many characters in the bookmark's title/URL are part of this match.
204 // (term length / title length). 208 // This is capped at the length of the bookmark's title
209 // to prevent terms that match in both the title and the URL from
210 // scoring too strongly.
205 // 211 //
206 // Example: Given a bookmark title 'abcde fghijklm', with a title length 212 // 2) where the match occurs within the bookmark's title or URL,
207 // of 14, and two different search terms, 'abcde' and 'fghijklm', with 213 // giving more points for matches that appear earlier in the string:
208 // term lengths of 5 and 8, respectively, 'fghijklm' will score higher 214 // ((string_length - position of match start) / string_length).
209 // (with a partial factor of 8/14 = 0.571) than 'abcde' (5/14 = 0.357).
210 //
211 // 2) where the term match occurs within the bookmark's title, giving more
212 // points for matches that appear earlier in the title:
213 // ((title length - position of match start) / title_length).
214 // 215 //
215 // Example: Given a bookmark title of 'abcde fghijklm', with a title length 216 // Example: Given a bookmark title of 'abcde fghijklm', with a title length
216 // of 14, and two different search terms, 'abcde' and 'fghij', with 217 // of 14, and two different search terms, 'abcde' and 'fghij', with
217 // start positions of 0 and 6, respectively, 'abcde' will score higher 218 // start positions of 0 and 6, respectively, 'abcde' will score higher
218 // (with a a partial factor of (14-0)/14 = 1.000 ) than 'fghij' (with 219 // (with a a partial factor of (14-0)/14 = 1.000 ) than 'fghij' (with
219 // a partial factor of (14-6)/14 = 0.571 ). 220 // a partial factor of (14-6)/14 = 0.571 ). (In this example neither
221 // term matches in the URL.)
220 // 222 //
221 // Once all term factors have been calculated they are summed. The resulting 223 // Once all match factors have been calculated they are summed. If URL
222 // sum will never be greater than 1.0 because of the way the bookmark model 224 // matches are not considered, the resulting sum will never be greater than
223 // matches and removes overlaps. (In particular, the bookmark model only 225 // the length of the bookmark title because of the way the bookmark model
226 // matches and removes overlaps. (In particular, the bookmark model only
224 // matches terms to the beginning of words and it removes all overlapping 227 // matches terms to the beginning of words and it removes all overlapping
225 // matches, keeping only the longest. Together these mean that each 228 // matches, keeping only the longest. Together these mean that each
226 // character is included in at most one match. This property ensures the 229 // character is included in at most one match.) If URL matches are
227 // sum of factors is at most 1.) This sum is then multiplied against the 230 // considered, the sum can be greater.
228 // scoring range available, which is 299. The 299 is calculated by 231 //
229 // subtracting the minimum possible score, 900, from the maximum possible 232 // This sum is then normalized by the length of the bookmark title (if URL
230 // score, 1199. This product, ranging from 0 to 299, is added to the minimum 233 // matches are not considered) or by the length of the bookmark title + 10
231 // possible score, 900, giving the preliminary score. 234 // (if URL matches are considered) and capped at 1.0. (If URL matches
235 // are considered, we want to expand the scoring range so fewer bookmarks
236 // will hit the 1.0 cap and hence lose all ability to distinguish between
237 // these high-quality bookmarks.)
238 //
239 // The normalized value is multiplied against the scoring range available,
240 // which is 299. The 299 is calculated by subtracting the minimum possible
241 // score, 900, from the maximum possible score, 1199. This product, ranging
242 // from 0 to 299, is added to the minimum possible score, 900, giving the
243 // preliminary score.
232 // 244 //
233 // If the preliminary score is less than the maximum possible score, 1199, 245 // If the preliminary score is less than the maximum possible score, 1199,
234 // it can be boosted up to that maximum possible score if the URL referenced 246 // it can be boosted up to that maximum possible score if the URL referenced
235 // by the bookmark is also referenced by any of the user's other bookmarks. 247 // by the bookmark is also referenced by any of the user's other bookmarks.
236 // A count of how many times the bookmark's URL is referenced is determined 248 // A count of how many times the bookmark's URL is referenced is determined
237 // and, for each additional reference beyond the one for the bookmark being 249 // and, for each additional reference beyond the one for the bookmark being
238 // scored up to a maximum of three, the score is boosted by a fixed amount 250 // scored up to a maximum of three, the score is boosted by a fixed amount
239 // given by |kURLCountBoost|, below. 251 // given by |kURLCountBoost|, below.
240 // 252 //
241 ScoringFunctor position_functor = 253 if (score_using_url_matches_) {
242 for_each(title_match.match_positions.begin(), 254 // Pretend empty titles are identical to the URL.
243 title_match.match_positions.end(), ScoringFunctor(title.size())); 255 if (title.empty())
256 title = base::ASCIIToUTF16(url.spec());
257 } else {
258 DCHECK(!title.empty());
259 }
260 ScoringFunctor title_position_functor =
261 for_each(bookmark_match.title_match_positions.begin(),
262 bookmark_match.title_match_positions.end(),
263 ScoringFunctor(title.size()));
264 ScoringFunctor url_position_functor =
265 for_each(bookmark_match.url_match_positions.begin(),
266 bookmark_match.url_match_positions.end(),
267 ScoringFunctor(bookmark_match.node->url().spec().length()));
268 const double summed_factors = title_position_functor.ScoringFactor() +
269 (score_using_url_matches_ ? url_position_functor.ScoringFactor() : 0);
270 const double normalized_sum = std::min(
271 summed_factors / (title.size() + (score_using_url_matches_ ? 10 : 0)),
272 1.0);
244 const int kBaseBookmarkScore = 900; 273 const int kBaseBookmarkScore = 900;
245 const int kMaxBookmarkScore = 1199; 274 const int kMaxBookmarkScore = 1199;
246 const double kBookmarkScoreRange = 275 const double kBookmarkScoreRange =
247 static_cast<double>(kMaxBookmarkScore - kBaseBookmarkScore); 276 static_cast<double>(kMaxBookmarkScore - kBaseBookmarkScore);
248 // It's not likely that GetBookmarksWithTitlesMatching will return overlapping 277 match.relevance = static_cast<int>(normalized_sum * kBookmarkScoreRange) +
249 // matches but let's play it safe. 278 kBaseBookmarkScore;
250 match.relevance = std::min(kMaxBookmarkScore,
251 static_cast<int>(position_functor.ScoringFactor() * kBookmarkScoreRange) +
252 kBaseBookmarkScore);
253 // Don't waste any time searching for additional referenced URLs if we 279 // Don't waste any time searching for additional referenced URLs if we
254 // already have a perfect title match. 280 // already have a perfect title match.
255 if (match.relevance >= kMaxBookmarkScore) 281 if (match.relevance >= kMaxBookmarkScore)
256 return match; 282 return match;
257 // Boost the score if the bookmark's URL is referenced by other bookmarks. 283 // Boost the score if the bookmark's URL is referenced by other bookmarks.
258 const int kURLCountBoost[4] = { 0, 75, 125, 150 }; 284 const int kURLCountBoost[4] = { 0, 75, 125, 150 };
259 std::vector<const BookmarkNode*> nodes; 285 std::vector<const BookmarkNode*> nodes;
260 bookmark_model_->GetNodesByURL(url, &nodes); 286 bookmark_model_->GetNodesByURL(url, &nodes);
261 DCHECK_GE(std::min(arraysize(kURLCountBoost), nodes.size()), 1U); 287 DCHECK_GE(std::min(arraysize(kURLCountBoost), nodes.size()), 1U);
262 match.relevance += 288 match.relevance +=
263 kURLCountBoost[std::min(arraysize(kURLCountBoost), nodes.size()) - 1]; 289 kURLCountBoost[std::min(arraysize(kURLCountBoost), nodes.size()) - 1];
264 match.relevance = std::min(kMaxBookmarkScore, match.relevance); 290 match.relevance = std::min(kMaxBookmarkScore, match.relevance);
265 return match; 291 return match;
266 } 292 }
267 293
268 // static 294 // static
269 ACMatchClassifications BookmarkProvider::ClassificationsFromMatch( 295 ACMatchClassifications BookmarkProvider::ClassificationsFromMatch(
270 const query_parser::Snippet::MatchPositions& positions, 296 const query_parser::Snippet::MatchPositions& positions,
271 size_t text_length) { 297 size_t text_length,
298 bool is_url) {
299 ACMatchClassification::Style url_style =
300 is_url ? ACMatchClassification::URL : ACMatchClassification::NONE;
272 ACMatchClassifications classifications; 301 ACMatchClassifications classifications;
273 if (positions.empty()) { 302 if (positions.empty()) {
274 classifications.push_back( 303 classifications.push_back(
275 ACMatchClassification(0, ACMatchClassification::NONE)); 304 ACMatchClassification(0, url_style));
276 return classifications; 305 return classifications;
277 } 306 }
278 307
279 for (query_parser::Snippet::MatchPositions::const_iterator i = 308 for (query_parser::Snippet::MatchPositions::const_iterator i =
280 positions.begin(); 309 positions.begin();
281 i != positions.end(); 310 i != positions.end();
282 ++i) { 311 ++i) {
283 AutocompleteMatch::ACMatchClassifications new_class; 312 AutocompleteMatch::ACMatchClassifications new_class;
284 AutocompleteMatch::ClassifyLocationInString(i->first, i->second - i->first, 313 AutocompleteMatch::ClassifyLocationInString(i->first, i->second - i->first,
285 text_length, 0, &new_class); 314 text_length, url_style, &new_class);
286 classifications = AutocompleteMatch::MergeClassifications( 315 classifications = AutocompleteMatch::MergeClassifications(
287 classifications, new_class); 316 classifications, new_class);
288 } 317 }
289 return classifications; 318 return classifications;
290 } 319 }
OLDNEW
« no previous file with comments | « chrome/browser/autocomplete/bookmark_provider.h ('k') | chrome/browser/autocomplete/bookmark_provider_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698