OLD | NEW |
---|---|
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 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/search_provider.h" | 5 #include "chrome/browser/autocomplete/search_provider.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <cmath> | 8 #include <cmath> |
9 | 9 |
10 #include "base/callback.h" | 10 #include "base/callback.h" |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
248 : AutocompleteProvider(listener, profile, | 248 : AutocompleteProvider(listener, profile, |
249 AutocompleteProvider::TYPE_SEARCH), | 249 AutocompleteProvider::TYPE_SEARCH), |
250 providers_(TemplateURLServiceFactory::GetForProfile(profile)), | 250 providers_(TemplateURLServiceFactory::GetForProfile(profile)), |
251 suggest_results_pending_(0), | 251 suggest_results_pending_(0), |
252 field_trial_triggered_(false), | 252 field_trial_triggered_(false), |
253 field_trial_triggered_in_session_(false), | 253 field_trial_triggered_in_session_(false), |
254 omnibox_start_margin_(-1), | 254 omnibox_start_margin_(-1), |
255 prevent_search_history_inlining_( | 255 prevent_search_history_inlining_( |
256 OmniboxFieldTrial::SearchHistoryPreventInlining()), | 256 OmniboxFieldTrial::SearchHistoryPreventInlining()), |
257 disable_search_history_( | 257 disable_search_history_( |
258 OmniboxFieldTrial::SearchHistoryDisable()) { | 258 OmniboxFieldTrial::SearchHistoryDisable()), |
259 omnibox_will_reorder_for_legal_default_match_( | |
260 OmniboxFieldTrial::InReorderForLegalDefaultMatchGroup()) { | |
259 } | 261 } |
260 | 262 |
261 // static | 263 // static |
262 AutocompleteMatch SearchProvider::CreateSearchSuggestion( | 264 AutocompleteMatch SearchProvider::CreateSearchSuggestion( |
263 AutocompleteProvider* autocomplete_provider, | 265 AutocompleteProvider* autocomplete_provider, |
264 int relevance, | 266 int relevance, |
265 AutocompleteMatch::Type type, | 267 AutocompleteMatch::Type type, |
266 const TemplateURL* template_url, | 268 const TemplateURL* template_url, |
267 const string16& query_string, | 269 const string16& query_string, |
268 const string16& input_text, | 270 const string16& input_text, |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
308 match.contents_class.push_back( | 310 match.contents_class.push_back( |
309 ACMatchClassification(next_fragment_position, | 311 ACMatchClassification(next_fragment_position, |
310 ACMatchClassification::MATCH)); | 312 ACMatchClassification::MATCH)); |
311 } | 313 } |
312 } | 314 } |
313 } else { | 315 } else { |
314 // Otherwise, we're dealing with the "default search" result which has no | 316 // Otherwise, we're dealing with the "default search" result which has no |
315 // completion. | 317 // completion. |
316 match.contents_class.push_back( | 318 match.contents_class.push_back( |
317 ACMatchClassification(0, ACMatchClassification::NONE)); | 319 ACMatchClassification(0, ACMatchClassification::NONE)); |
320 match.allowed_to_be_default_match = true; | |
318 } | 321 } |
319 | 322 |
320 // When the user forced a query, we need to make sure all the fill_into_edit | 323 // When the user forced a query, we need to make sure all the fill_into_edit |
321 // values preserve that property. Otherwise, if the user starts editing a | 324 // values preserve that property. Otherwise, if the user starts editing a |
322 // suggestion, non-Search results will suddenly appear. | 325 // suggestion, non-Search results will suddenly appear. |
323 if (input.type() == AutocompleteInput::FORCED_QUERY) | 326 if (input.type() == AutocompleteInput::FORCED_QUERY) |
324 match.fill_into_edit.assign(ASCIIToUTF16("?")); | 327 match.fill_into_edit.assign(ASCIIToUTF16("?")); |
325 if (is_keyword) | 328 if (is_keyword) |
326 match.fill_into_edit.append(match.keyword + char16(' ')); | 329 match.fill_into_edit.append(match.keyword + char16(' ')); |
327 if (!input.prevent_inline_autocomplete() && | 330 if (!input.prevent_inline_autocomplete() && |
328 StartsWith(query_string, input_text, false)) { | 331 StartsWith(query_string, input_text, false)) { |
329 match.inline_autocomplete_offset = | 332 match.inline_autocomplete_offset = |
330 match.fill_into_edit.length() + input_text.length(); | 333 match.fill_into_edit.length() + input_text.length(); |
334 match.allowed_to_be_default_match = true; | |
331 } | 335 } |
332 match.fill_into_edit.append(query_string); | 336 match.fill_into_edit.append(query_string); |
333 | 337 |
334 const TemplateURLRef& search_url = template_url->url_ref(); | 338 const TemplateURLRef& search_url = template_url->url_ref(); |
335 DCHECK(search_url.SupportsReplacement()); | 339 DCHECK(search_url.SupportsReplacement()); |
336 match.search_terms_args.reset( | 340 match.search_terms_args.reset( |
337 new TemplateURLRef::SearchTermsArgs(query_string)); | 341 new TemplateURLRef::SearchTermsArgs(query_string)); |
338 match.search_terms_args->original_query = input_text; | 342 match.search_terms_args->original_query = input_text; |
339 match.search_terms_args->accepted_suggestion = accepted_suggestion; | 343 match.search_terms_args->accepted_suggestion = accepted_suggestion; |
340 match.search_terms_args->omnibox_start_margin = omnibox_start_margin; | 344 match.search_terms_args->omnibox_start_margin = omnibox_start_margin; |
(...skipping 724 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1065 | 1069 |
1066 bool SearchProvider::IsTopMatchHighRankSearchForURL() const { | 1070 bool SearchProvider::IsTopMatchHighRankSearchForURL() const { |
1067 return input_.type() == AutocompleteInput::URL && | 1071 return input_.type() == AutocompleteInput::URL && |
1068 matches_.front().relevance > CalculateRelevanceForVerbatim() && | 1072 matches_.front().relevance > CalculateRelevanceForVerbatim() && |
1069 (matches_.front().type == AutocompleteMatchType::SEARCH_SUGGEST || | 1073 (matches_.front().type == AutocompleteMatchType::SEARCH_SUGGEST || |
1070 matches_.front().type == | 1074 matches_.front().type == |
1071 AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED || | 1075 AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED || |
1072 matches_.front().type == AutocompleteMatchType::SEARCH_OTHER_ENGINE); | 1076 matches_.front().type == AutocompleteMatchType::SEARCH_OTHER_ENGINE); |
1073 } | 1077 } |
1074 | 1078 |
1075 bool SearchProvider::IsTopMatchNotInlinable() const { | 1079 bool SearchProvider::IsTopMatchNotAllowedToBeDefaultMatch() const { |
1076 // Note: this test assumes the SEARCH_OTHER_ENGINE match corresponds to | 1080 return !matches_.front().allowed_to_be_default_match; |
1077 // the verbatim search query on the keyword engine. SearchProvider should | 1081 } |
1078 // not create any other match of type SEARCH_OTHER_ENGINE. | 1082 |
1079 return | 1083 bool SearchProvider::LacksDefaultMatch() const { |
1080 matches_.front().type != AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED && | 1084 for (ACMatches::const_iterator it = matches_.begin(); it != matches_.end(); |
1081 matches_.front().type != AutocompleteMatchType::SEARCH_OTHER_ENGINE && | 1085 ++it) { |
1082 matches_.front().inline_autocomplete_offset == string16::npos && | 1086 if (it->allowed_to_be_default_match) |
1083 matches_.front().fill_into_edit != input_.text(); | 1087 return false; |
1088 } | |
1089 return true; | |
1084 } | 1090 } |
1085 | 1091 |
1086 void SearchProvider::UpdateMatches() { | 1092 void SearchProvider::UpdateMatches() { |
1087 ConvertResultsToAutocompleteMatches(); | 1093 ConvertResultsToAutocompleteMatches(); |
1088 | 1094 |
1089 // Check constraints that may be violated by suggested relevances. | 1095 // Check constraints that may be violated by suggested relevances. |
1090 if (!matches_.empty() && | 1096 if (!matches_.empty() && |
1091 (default_results_.HasServerProvidedScores() || | 1097 (default_results_.HasServerProvidedScores() || |
1092 keyword_results_.HasServerProvidedScores())) { | 1098 keyword_results_.HasServerProvidedScores())) { |
1093 // These blocks attempt to repair undesirable behavior by suggested | 1099 // These blocks attempt to repair undesirable behavior by suggested |
(...skipping 24 matching lines...) Expand all Loading... | |
1118 // Disregard the suggested search and verbatim relevances if the input | 1124 // Disregard the suggested search and verbatim relevances if the input |
1119 // type is URL and the top match is a highly-ranked search suggestion. | 1125 // type is URL and the top match is a highly-ranked search suggestion. |
1120 // For example, prevent a search for "foo.com" from outranking another | 1126 // For example, prevent a search for "foo.com" from outranking another |
1121 // provider's navigation for "foo.com" or "foo.com/url_from_history". | 1127 // provider's navigation for "foo.com" or "foo.com/url_from_history". |
1122 ApplyCalculatedSuggestRelevance(&keyword_results_.suggest_results); | 1128 ApplyCalculatedSuggestRelevance(&keyword_results_.suggest_results); |
1123 ApplyCalculatedSuggestRelevance(&default_results_.suggest_results); | 1129 ApplyCalculatedSuggestRelevance(&default_results_.suggest_results); |
1124 default_results_.verbatim_relevance = -1; | 1130 default_results_.verbatim_relevance = -1; |
1125 keyword_results_.verbatim_relevance = -1; | 1131 keyword_results_.verbatim_relevance = -1; |
1126 ConvertResultsToAutocompleteMatches(); | 1132 ConvertResultsToAutocompleteMatches(); |
1127 } | 1133 } |
1128 if (IsTopMatchNotInlinable()) { | 1134 if ((!omnibox_will_reorder_for_legal_default_match_ && |
Peter Kasting
2013/07/17 18:29:48
Nit: Simpler:
if (omnibox_will_reorder_for_le
Mark P
2013/07/17 20:39:18
Done.
| |
1129 // Disregard suggested relevances if the top match is not a verbatim match | 1135 IsTopMatchNotAllowedToBeDefaultMatch()) || |
1130 // or inlinable. For example, input "foo" should not invoke a search for | 1136 (omnibox_will_reorder_for_legal_default_match_ && |
1131 // "bar", which would happen if the "bar" search match outranked all other | 1137 LacksDefaultMatch())) { |
1132 // matches. | 1138 // Disregard suggested relevances if either: |
1139 // * the top match is not allowed to be the default match (i.e., it's not | |
1140 // either a verbatim match or inlinable). For example, input "foo" | |
1141 // should not invoke a search for "bar", which would happen if the | |
1142 // "bar" search match outranked all other matches. We only care | |
1143 // about this condition if the omnibox itself will not reorder | |
1144 // matches to put a legal default match on top. | |
1145 // * no matches are allowed to be the default match. SearchProvider is | |
1146 // supposed to return a legal default match for any input. We need | |
1147 // to make sure it does so. This constraint should be true always, | |
1148 // but we only need to check it if | |
1149 // |omnibox_will_reorder_for_legal_default_match_|. (If that were | |
1150 // false, the first part of the test above will suffice.) | |
1133 ApplyCalculatedRelevance(); | 1151 ApplyCalculatedRelevance(); |
1134 ConvertResultsToAutocompleteMatches(); | 1152 ConvertResultsToAutocompleteMatches(); |
1135 } | 1153 } |
1136 DCHECK(!IsTopMatchNavigationInKeywordMode()); | 1154 DCHECK(!IsTopMatchNavigationInKeywordMode()); |
1137 DCHECK(!IsTopMatchScoreTooLow()); | 1155 DCHECK(!IsTopMatchScoreTooLow()); |
1138 DCHECK(!IsTopMatchHighRankSearchForURL()); | 1156 DCHECK(!IsTopMatchHighRankSearchForURL()); |
1139 DCHECK(!IsTopMatchNotInlinable()); | 1157 DCHECK(omnibox_will_reorder_for_legal_default_match_ || |
1158 !IsTopMatchNotAllowedToBeDefaultMatch()); | |
1159 DCHECK(!LacksDefaultMatch()); | |
1140 } | 1160 } |
1141 | 1161 |
1142 UpdateStarredStateOfMatches(); | 1162 UpdateStarredStateOfMatches(); |
1143 UpdateDone(); | 1163 UpdateDone(); |
1144 } | 1164 } |
1145 | 1165 |
1146 void SearchProvider::AddNavigationResultsToMatches( | 1166 void SearchProvider::AddNavigationResultsToMatches( |
1147 const NavigationResults& navigation_results, | 1167 const NavigationResults& navigation_results, |
1148 ACMatches* matches) { | 1168 ACMatches* matches) { |
1149 for (NavigationResults::const_iterator it = navigation_results.begin(); | 1169 for (NavigationResults::const_iterator it = navigation_results.begin(); |
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1516 it->set_relevance(max_query_relevance); | 1536 it->set_relevance(max_query_relevance); |
1517 it->set_relevance_from_server(relevance_from_server); | 1537 it->set_relevance_from_server(relevance_from_server); |
1518 } | 1538 } |
1519 } | 1539 } |
1520 | 1540 |
1521 void SearchProvider::UpdateDone() { | 1541 void SearchProvider::UpdateDone() { |
1522 // We're done when the timer isn't running, there are no suggest queries | 1542 // We're done when the timer isn't running, there are no suggest queries |
1523 // pending, and we're not waiting on Instant. | 1543 // pending, and we're not waiting on Instant. |
1524 done_ = !timer_.IsRunning() && (suggest_results_pending_ == 0); | 1544 done_ = !timer_.IsRunning() && (suggest_results_pending_ == 0); |
1525 } | 1545 } |
OLD | NEW |