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

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: Created 6 years, 9 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/metrics/histogram.h" 11 #include "base/metrics/histogram.h"
12 #include "base/prefs/pref_service.h" 12 #include "base/prefs/pref_service.h"
13 #include "base/time/time.h" 13 #include "base/time/time.h"
14 #include "chrome/browser/autocomplete/autocomplete_result.h" 14 #include "chrome/browser/autocomplete/autocomplete_result.h"
15 #include "chrome/browser/bookmarks/bookmark_match.h"
15 #include "chrome/browser/bookmarks/bookmark_model.h" 16 #include "chrome/browser/bookmarks/bookmark_model.h"
16 #include "chrome/browser/bookmarks/bookmark_model_factory.h" 17 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
17 #include "chrome/browser/bookmarks/bookmark_title_match.h"
18 #include "chrome/browser/profiles/profile.h" 18 #include "chrome/browser/profiles/profile.h"
19 #include "chrome/common/pref_names.h" 19 #include "chrome/common/pref_names.h"
20 #include "net/base/net_util.h" 20 #include "net/base/net_util.h"
21 21
22 typedef std::vector<BookmarkTitleMatch> TitleMatches; 22 typedef std::vector<BookmarkMatch> BookmarkMatches;
23 23
24 // BookmarkProvider ------------------------------------------------------------ 24 // BookmarkProvider ------------------------------------------------------------
25 25
26 BookmarkProvider::BookmarkProvider( 26 BookmarkProvider::BookmarkProvider(
27 AutocompleteProviderListener* listener, 27 AutocompleteProviderListener* listener,
28 Profile* profile) 28 Profile* profile)
29 : AutocompleteProvider(listener, profile, 29 : AutocompleteProvider(listener, profile,
30 AutocompleteProvider::TYPE_BOOKMARK), 30 AutocompleteProvider::TYPE_BOOKMARK),
31 bookmark_model_(NULL) { 31 bookmark_model_(NULL) {
32 if (profile) { 32 if (profile) {
(...skipping 26 matching lines...) Expand all
59 } 59 }
60 60
61 BookmarkProvider::~BookmarkProvider() {} 61 BookmarkProvider::~BookmarkProvider() {}
62 62
63 void BookmarkProvider::DoAutocomplete(const AutocompleteInput& input, 63 void BookmarkProvider::DoAutocomplete(const AutocompleteInput& input,
64 bool best_match) { 64 bool best_match) {
65 // We may not have a bookmark model for some unit tests. 65 // We may not have a bookmark model for some unit tests.
66 if (!bookmark_model_) 66 if (!bookmark_model_)
67 return; 67 return;
68 68
69 TitleMatches matches; 69 BookmarkMatches matches;
70 // Retrieve enough bookmarks so that we have a reasonable probability of 70 // Retrieve enough bookmarks so that we have a reasonable probability of
71 // suggesting the one that the user desires. 71 // suggesting the one that the user desires.
72 const size_t kMaxBookmarkMatches = 50; 72 const size_t kMaxBookmarkMatches = 50;
73 73
74 // GetBookmarksWithTitlesMatching returns bookmarks matching the user's 74 // GetBookmarksMatching returns bookmarks matching the user's
75 // search terms using the following rules: 75 // search terms using the following rules:
76 // - The search text is broken up into search terms. Each term is searched 76 // - The search text is broken up into search terms. Each term is searched
77 // for separately. 77 // for separately.
78 // - Term matches are always performed against the start of a word. 'def' 78 // - Term matches are always performed against the start of a word. 'def'
79 // will match against 'define' but not against 'indefinite'. 79 // will match against 'define' but not against 'indefinite'.
80 // - Terms must be at least three characters in length in order to perform 80 // - Terms must be at least three characters in length in order to perform
81 // partial word matches. Any term of lesser length will only be used as an 81 // partial word matches. Any term of lesser length will only be used as an
82 // exact match. 'def' will match against 'define' but 'de' will not match. 82 // exact match. 'def' will match against 'define' but 'de' will not match.
83 // - A search containing multiple terms will return results with those words 83 // - A search containing multiple terms will return results with those words
84 // occuring in any order. 84 // occuring in any order.
85 // - Terms enclosed in quotes comprises a phrase that must match exactly. 85 // - Terms enclosed in quotes comprises a phrase that must match exactly.
86 // - Multiple terms enclosed in quotes will require those exact words in that 86 // - Multiple terms enclosed in quotes will require those exact words in that
87 // exact order to match. 87 // exact order to match.
88 // 88 //
89 // Note: GetBookmarksWithTitlesMatching() will never return a match span 89 // *** REVISE THIS
90 // greater than the length of the title against which it is being matched, 90 // Note: GetBookmarksMatching() will never return a match span greater than
91 // the length of the title against which it is being matched,
91 // nor can those spans ever overlap because the match spans are coalesced 92 // nor can those spans ever overlap because the match spans are coalesced
92 // for all matched terms. 93 // for all matched terms.
93 // 94 //
94 // Please refer to the code for BookmarkIndex::GetBookmarksWithTitlesMatching 95 // Please refer to the code for BookmarkIndex::GetBookmarksMatching for
95 // for complete details of how title searches are performed against the user's 96 // complete details of how title searches are performed against the user's
96 // bookmarks. 97 // bookmarks.
97 bookmark_model_->GetBookmarksWithTitlesMatching(input.text(), 98 bookmark_model_->GetBookmarksMatching(input.text(),
98 kMaxBookmarkMatches, 99 kMaxBookmarkMatches,
99 &matches); 100 &matches);
100 if (matches.empty()) 101 if (matches.empty())
101 return; // There were no matches. 102 return; // There were no matches.
102 for (TitleMatches::const_iterator i = matches.begin(); i != matches.end(); 103 for (BookmarkMatches::const_iterator i = matches.begin(); i != matches.end();
103 ++i) { 104 ++i) {
104 // Create and score the AutocompleteMatch. If its score is 0 then the 105 // Create and score the AutocompleteMatch. If its score is 0 then the
105 // match is discarded. 106 // match is discarded.
106 AutocompleteMatch match(TitleMatchToACMatch(*i)); 107 AutocompleteMatch match(BookmarkMatchToACMatch(*i));
107 if (match.relevance > 0) 108 if (match.relevance > 0)
108 matches_.push_back(match); 109 matches_.push_back(match);
109 } 110 }
110 111
111 // Sort and clip the resulting matches. 112 // Sort and clip the resulting matches.
112 size_t max_matches = best_match ? 1 : AutocompleteProvider::kMaxMatches; 113 size_t max_matches = best_match ? 1 : AutocompleteProvider::kMaxMatches;
113 if (matches_.size() > max_matches) { 114 if (matches_.size() > max_matches) {
114 std::partial_sort(matches_.begin(), 115 std::partial_sort(matches_.begin(),
115 matches_.begin() + max_matches, 116 matches_.begin() + max_matches,
116 matches_.end(), 117 matches_.end(),
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 151
151 double ScoringFactor() { return scoring_factor_; } 152 double ScoringFactor() { return scoring_factor_; }
152 153
153 private: 154 private:
154 double title_length_; 155 double title_length_;
155 double scoring_factor_; 156 double scoring_factor_;
156 }; 157 };
157 158
158 } // namespace 159 } // namespace
159 160
160 AutocompleteMatch BookmarkProvider::TitleMatchToACMatch( 161 AutocompleteMatch BookmarkProvider::BookmarkMatchToACMatch(
161 const BookmarkTitleMatch& title_match) { 162 const BookmarkMatch& title_match) {
162 // The AutocompleteMatch we construct is non-deletable because the only 163 // The AutocompleteMatch we construct is non-deletable because the only
163 // way to support this would be to delete the underlying bookmark, which is 164 // way to support this would be to delete the underlying bookmark, which is
164 // unlikely to be what the user intends. 165 // unlikely to be what the user intends.
165 AutocompleteMatch match(this, 0, false, 166 AutocompleteMatch match(this, 0, false,
166 AutocompleteMatchType::BOOKMARK_TITLE); 167 AutocompleteMatchType::BOOKMARK_TITLE);
167 const base::string16& title(title_match.node->GetTitle()); 168 const base::string16& title(title_match.node->GetTitle());
168 DCHECK(!title.empty()); 169 DCHECK(!title.empty());
169 const GURL& url(title_match.node->url()); 170 const GURL& url(title_match.node->url());
170 match.destination_url = url; 171 match.destination_url = url;
171 match.contents = net::FormatUrl(url, languages_, 172 match.contents = net::FormatUrl(url, languages_,
172 net::kFormatUrlOmitAll & net::kFormatUrlOmitHTTP, 173 net::kFormatUrlOmitAll & net::kFormatUrlOmitHTTP,
173 net::UnescapeRule::SPACES, NULL, NULL, NULL); 174 net::UnescapeRule::SPACES, NULL, NULL, NULL);
174 match.contents_class.push_back( 175 match.contents_class.push_back(
175 ACMatchClassification(0, ACMatchClassification::URL)); 176 ACMatchClassification(0, ACMatchClassification::URL));
176 match.fill_into_edit = 177 match.fill_into_edit =
177 AutocompleteInput::FormattedStringWithEquivalentMeaning(url, 178 AutocompleteInput::FormattedStringWithEquivalentMeaning(url,
178 match.contents); 179 match.contents);
179 match.description = title; 180 match.description = title;
180 match.description_class = 181 match.description_class =
181 ClassificationsFromMatch(title_match.match_positions, 182 ClassificationsFromMatch(title_match.title_match_positions,
182 match.description.size()); 183 match.description.size());
183 match.starred = true; 184 match.starred = true;
184 185
185 // Summary on how a relevance score is determined for the match: 186 // Summary on how a relevance score is determined for the match:
186 // 187 //
188 // *** REVISE THIS
189 //
187 // For each term matching within the bookmark's title (as given by the set of 190 // For each term matching within the bookmark's title (as given by the set of
188 // Snippet::MatchPositions) calculate a 'factor', sum up those factors, then 191 // Snippet::MatchPositions) calculate a 'factor', sum up those factors, then
189 // use the sum to figure out a value between the base score and the maximum 192 // use the sum to figure out a value between the base score and the maximum
190 // score. 193 // score.
191 // 194 //
192 // The factor for each term is the product of: 195 // The factor for each term is the product of:
193 // 196 //
194 // 1) how much of the bookmark's title has been matched by the term: 197 // 1) how much of the bookmark's title has been matched by the term:
195 // (term length / title length). 198 // (term length / title length).
196 // 199 //
(...skipping 26 matching lines...) Expand all
223 // 226 //
224 // If the preliminary score is less than the maximum possible score, 1199, 227 // If the preliminary score is less than the maximum possible score, 1199,
225 // it can be boosted up to that maximum possible score if the URL referenced 228 // it can be boosted up to that maximum possible score if the URL referenced
226 // by the bookmark is also referenced by any of the user's other bookmarks. 229 // by the bookmark is also referenced by any of the user's other bookmarks.
227 // A count of how many times the bookmark's URL is referenced is determined 230 // A count of how many times the bookmark's URL is referenced is determined
228 // and, for each additional reference beyond the one for the bookmark being 231 // and, for each additional reference beyond the one for the bookmark being
229 // scored up to a maximum of three, the score is boosted by a fixed amount 232 // scored up to a maximum of three, the score is boosted by a fixed amount
230 // given by |kURLCountBoost|, below. 233 // given by |kURLCountBoost|, below.
231 // 234 //
232 ScoringFunctor position_functor = 235 ScoringFunctor position_functor =
233 for_each(title_match.match_positions.begin(), 236 for_each(title_match.title_match_positions.begin(),
234 title_match.match_positions.end(), ScoringFunctor(title.size())); 237 title_match.title_match_positions.end(),
238 ScoringFunctor(title.size()));
235 const int kBaseBookmarkScore = 900; 239 const int kBaseBookmarkScore = 900;
236 const int kMaxBookmarkScore = AutocompleteResult::kLowestDefaultScore - 1; 240 const int kMaxBookmarkScore = AutocompleteResult::kLowestDefaultScore - 1;
237 const double kBookmarkScoreRange = 241 const double kBookmarkScoreRange =
238 static_cast<double>(kMaxBookmarkScore - kBaseBookmarkScore); 242 static_cast<double>(kMaxBookmarkScore - kBaseBookmarkScore);
239 // It's not likely that GetBookmarksWithTitlesMatching will return overlapping 243 // It's not likely that GetBookmarksWithTitlesMatching will return overlapping
240 // matches but let's play it safe. 244 // matches but let's play it safe.
241 match.relevance = std::min(kMaxBookmarkScore, 245 match.relevance = std::min(kMaxBookmarkScore,
242 static_cast<int>(position_functor.ScoringFactor() * kBookmarkScoreRange) + 246 static_cast<int>(position_functor.ScoringFactor() * kBookmarkScoreRange) +
243 kBaseBookmarkScore); 247 kBaseBookmarkScore);
244 // Don't waste any time searching for additional referenced URLs if we 248 // Don't waste any time searching for additional referenced URLs if we
(...skipping 25 matching lines...) Expand all
270 for (Snippet::MatchPositions::const_iterator i = positions.begin(); 274 for (Snippet::MatchPositions::const_iterator i = positions.begin();
271 i != positions.end(); ++i) { 275 i != positions.end(); ++i) {
272 AutocompleteMatch::ACMatchClassifications new_class; 276 AutocompleteMatch::ACMatchClassifications new_class;
273 AutocompleteMatch::ClassifyLocationInString(i->first, i->second - i->first, 277 AutocompleteMatch::ClassifyLocationInString(i->first, i->second - i->first,
274 text_length, 0, &new_class); 278 text_length, 0, &new_class);
275 classifications = AutocompleteMatch::MergeClassifications( 279 classifications = AutocompleteMatch::MergeClassifications(
276 classifications, new_class); 280 classifications, new_class);
277 } 281 }
278 return classifications; 282 return classifications;
279 } 283 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698