OLD | NEW |
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/chrome_autocomplete_scheme_classifier.h" | 13 #include "chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.h" |
14 #include "chrome/browser/autocomplete/history_provider.h" | 14 #include "chrome/browser/autocomplete/history_provider.h" |
15 #include "chrome/browser/bookmarks/bookmark_model_factory.h" | 15 #include "chrome/browser/bookmarks/bookmark_model_factory.h" |
16 #include "chrome/browser/profiles/profile.h" | 16 #include "chrome/browser/profiles/profile.h" |
17 #include "chrome/common/pref_names.h" | 17 #include "chrome/common/pref_names.h" |
18 #include "components/bookmarks/browser/bookmark_match.h" | 18 #include "components/bookmarks/browser/bookmark_match.h" |
19 #include "components/bookmarks/browser/bookmark_model.h" | 19 #include "components/bookmarks/browser/bookmark_model.h" |
20 #include "components/metrics/proto/omnibox_input_type.pb.h" | 20 #include "components/metrics/proto/omnibox_input_type.pb.h" |
21 #include "components/omnibox/autocomplete_result.h" | 21 #include "components/omnibox/autocomplete_result.h" |
| 22 #include "components/omnibox/omnibox_field_trial.h" |
22 #include "components/omnibox/url_prefix.h" | 23 #include "components/omnibox/url_prefix.h" |
23 #include "net/base/net_util.h" | 24 #include "net/base/net_util.h" |
24 | 25 |
25 using bookmarks::BookmarkMatch; | 26 using bookmarks::BookmarkMatch; |
26 | 27 |
27 typedef std::vector<BookmarkMatch> BookmarkMatches; | 28 typedef std::vector<BookmarkMatch> BookmarkMatches; |
28 | 29 |
29 // BookmarkProvider ------------------------------------------------------------ | 30 // BookmarkProvider ------------------------------------------------------------ |
30 | 31 |
31 BookmarkProvider::BookmarkProvider(Profile* profile) | 32 BookmarkProvider::BookmarkProvider(Profile* profile) |
32 : AutocompleteProvider(AutocompleteProvider::TYPE_BOOKMARK), | 33 : AutocompleteProvider(AutocompleteProvider::TYPE_BOOKMARK), |
33 profile_(profile), | 34 profile_(profile), |
34 bookmark_model_(NULL) { | 35 bookmark_model_(NULL), |
| 36 score_using_url_matches_(OmniboxFieldTrial::BookmarksIndexURLsValue()) { |
35 if (profile) { | 37 if (profile) { |
36 bookmark_model_ = BookmarkModelFactory::GetForProfile(profile); | 38 bookmark_model_ = BookmarkModelFactory::GetForProfile(profile); |
37 languages_ = profile_->GetPrefs()->GetString(prefs::kAcceptLanguages); | 39 languages_ = profile_->GetPrefs()->GetString(prefs::kAcceptLanguages); |
38 } | 40 } |
39 } | 41 } |
40 | 42 |
41 void BookmarkProvider::Start(const AutocompleteInput& input, | 43 void BookmarkProvider::Start(const AutocompleteInput& input, |
42 bool minimal_changes) { | 44 bool minimal_changes) { |
43 if (minimal_changes) | 45 if (minimal_changes) |
44 return; | 46 return; |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
211 // giving more points for matches that appear earlier in the string: | 213 // giving more points for matches that appear earlier in the string: |
212 // ((string_length - position of match start) / string_length). | 214 // ((string_length - position of match start) / string_length). |
213 // | 215 // |
214 // 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 |
215 // of 14, and two different search terms, 'abcde' and 'fghij', with | 217 // of 14, and two different search terms, 'abcde' and 'fghij', with |
216 // start positions of 0 and 6, respectively, 'abcde' will score higher | 218 // start positions of 0 and 6, respectively, 'abcde' will score higher |
217 // (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 |
218 // a partial factor of (14-6)/14 = 0.571 ). (In this example neither | 220 // a partial factor of (14-6)/14 = 0.571 ). (In this example neither |
219 // term matches in the URL.) | 221 // term matches in the URL.) |
220 // | 222 // |
221 // Once all match factors have been calculated they are summed. If there | 223 // Once all match factors have been calculated they are summed. If URL |
222 // are no URL matches, the resulting sum will never be greater than the | 224 // matches are not considered, the resulting sum will never be greater than |
223 // length of the bookmark title because of the way the bookmark model matches | 225 // the length of the bookmark title because of the way the bookmark model |
224 // and removes overlaps. (In particular, the bookmark model only | 226 // matches and removes overlaps. (In particular, the bookmark model only |
225 // 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 |
226 // matches, keeping only the longest. Together these mean that each | 228 // matches, keeping only the longest. Together these mean that each |
227 // character is included in at most one match.) If there are matches in the | 229 // character is included in at most one match.) If URL matches are |
228 // URL, the sum can be greater. | 230 // considered, the sum can be greater. |
229 // | 231 // |
230 // This sum is then normalized by the length of the bookmark title + 10 | 232 // This sum is then normalized by the length of the bookmark title (if URL |
231 // and capped at 1.0. The +10 is to expand the scoring range so fewer | 233 // matches are not considered) or by the length of the bookmark title + 10 |
232 // bookmarks will hit the 1.0 cap and hence lose all ability to distinguish | 234 // (if URL matches are considered) and capped at 1.0. (If URL matches |
233 // between these high-quality bookmarks. | 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.) |
234 // | 238 // |
235 // The normalized value is multiplied against the scoring range available, | 239 // The normalized value is multiplied against the scoring range available, |
236 // which is 299. The 299 is calculated by subtracting the minimum possible | 240 // which is 299. The 299 is calculated by subtracting the minimum possible |
237 // score, 900, from the maximum possible score, 1199. This product, ranging | 241 // score, 900, from the maximum possible score, 1199. This product, ranging |
238 // from 0 to 299, is added to the minimum possible score, 900, giving the | 242 // from 0 to 299, is added to the minimum possible score, 900, giving the |
239 // preliminary score. | 243 // preliminary score. |
240 // | 244 // |
241 // 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, |
242 // 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 |
243 // 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. |
244 // 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 |
245 // 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 |
246 // 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 |
247 // given by |kURLCountBoost|, below. | 251 // given by |kURLCountBoost|, below. |
248 // | 252 // |
249 | 253 if (score_using_url_matches_) { |
250 // Pretend empty titles are identical to the URL. | 254 // Pretend empty titles are identical to the URL. |
251 if (title.empty()) | 255 if (title.empty()) |
252 title = base::ASCIIToUTF16(url.spec()); | 256 title = base::ASCIIToUTF16(url.spec()); |
| 257 } else { |
| 258 DCHECK(!title.empty()); |
| 259 } |
253 ScoringFunctor title_position_functor = | 260 ScoringFunctor title_position_functor = |
254 for_each(bookmark_match.title_match_positions.begin(), | 261 for_each(bookmark_match.title_match_positions.begin(), |
255 bookmark_match.title_match_positions.end(), | 262 bookmark_match.title_match_positions.end(), |
256 ScoringFunctor(title.size())); | 263 ScoringFunctor(title.size())); |
257 ScoringFunctor url_position_functor = | 264 ScoringFunctor url_position_functor = |
258 for_each(bookmark_match.url_match_positions.begin(), | 265 for_each(bookmark_match.url_match_positions.begin(), |
259 bookmark_match.url_match_positions.end(), | 266 bookmark_match.url_match_positions.end(), |
260 ScoringFunctor(bookmark_match.node->url().spec().length())); | 267 ScoringFunctor(bookmark_match.node->url().spec().length())); |
261 const double summed_factors = title_position_functor.ScoringFactor() + | 268 const double summed_factors = title_position_functor.ScoringFactor() + |
262 url_position_functor.ScoringFactor(); | 269 (score_using_url_matches_ ? url_position_functor.ScoringFactor() : 0); |
263 const double normalized_sum = | 270 const double normalized_sum = std::min( |
264 std::min(summed_factors / (title.size() + 10), 1.0); | 271 summed_factors / (title.size() + (score_using_url_matches_ ? 10 : 0)), |
| 272 1.0); |
265 const int kBaseBookmarkScore = 900; | 273 const int kBaseBookmarkScore = 900; |
266 const int kMaxBookmarkScore = 1199; | 274 const int kMaxBookmarkScore = 1199; |
267 const double kBookmarkScoreRange = | 275 const double kBookmarkScoreRange = |
268 static_cast<double>(kMaxBookmarkScore - kBaseBookmarkScore); | 276 static_cast<double>(kMaxBookmarkScore - kBaseBookmarkScore); |
269 match.relevance = static_cast<int>(normalized_sum * kBookmarkScoreRange) + | 277 match.relevance = static_cast<int>(normalized_sum * kBookmarkScoreRange) + |
270 kBaseBookmarkScore; | 278 kBaseBookmarkScore; |
271 // 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 |
272 // already have a perfect title match. | 280 // already have a perfect title match. |
273 if (match.relevance >= kMaxBookmarkScore) | 281 if (match.relevance >= kMaxBookmarkScore) |
274 return match; | 282 return match; |
(...skipping 27 matching lines...) Expand all Loading... |
302 i != positions.end(); | 310 i != positions.end(); |
303 ++i) { | 311 ++i) { |
304 AutocompleteMatch::ACMatchClassifications new_class; | 312 AutocompleteMatch::ACMatchClassifications new_class; |
305 AutocompleteMatch::ClassifyLocationInString(i->first, i->second - i->first, | 313 AutocompleteMatch::ClassifyLocationInString(i->first, i->second - i->first, |
306 text_length, url_style, &new_class); | 314 text_length, url_style, &new_class); |
307 classifications = AutocompleteMatch::MergeClassifications( | 315 classifications = AutocompleteMatch::MergeClassifications( |
308 classifications, new_class); | 316 classifications, new_class); |
309 } | 317 } |
310 return classifications; | 318 return classifications; |
311 } | 319 } |
OLD | NEW |