1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef COMPONENTS_OMNIBOX_SEARCH_SUGGESTION_PARSER_H_
6 #define COMPONENTS_OMNIBOX_SEARCH_SUGGESTION_PARSER_H_
11 #include "base/basictypes.h"
12 #include "base/gtest_prod_util.h"
13 #include "base/strings/string16.h"
14 #include "components/omnibox/autocomplete_match.h"
15 #include "components/omnibox/autocomplete_match_type.h"
18 class AutocompleteInput
;
19 class AutocompleteSchemeClassifier
;
22 class DictionaryValue
;
30 class SearchSuggestionParser
{
32 // The Result classes are intermediate representations of AutocompleteMatches,
33 // simply containing relevance-ranked search and navigation suggestions.
34 // They may be cached to provide some synchronous matches while requests for
35 // new suggestions from updated input are in flight.
36 // TODO(msw) Extend these classes to generate their corresponding matches and
37 // other requisite data, in order to consolidate and simplify the
38 // highly fragmented SearchProvider logic for each Result type.
41 Result(bool from_keyword_provider
,
43 bool relevance_from_server
,
44 AutocompleteMatchType::Type type
,
45 const std::string
& deletion_url
);
48 bool from_keyword_provider() const { return from_keyword_provider_
; }
50 const base::string16
& match_contents() const { return match_contents_
; }
51 const ACMatchClassifications
& match_contents_class() const {
52 return match_contents_class_
;
55 AutocompleteMatchType::Type
type() const { return type_
; }
56 int relevance() const { return relevance_
; }
57 void set_relevance(int relevance
) { relevance_
= relevance
; }
59 bool relevance_from_server() const { return relevance_from_server_
; }
60 void set_relevance_from_server(bool relevance_from_server
) {
61 relevance_from_server_
= relevance_from_server
;
64 const std::string
& deletion_url() const { return deletion_url_
; }
66 // Returns the default relevance value for this result (which may
67 // be left over from a previous omnibox input) given the current
68 // input and whether the current input caused a keyword provider
70 virtual int CalculateRelevance(const AutocompleteInput
& input
,
71 bool keyword_provider_requested
) const = 0;
74 // The contents to be displayed and its style info.
75 base::string16 match_contents_
;
76 ACMatchClassifications match_contents_class_
;
78 // True if the result came from the keyword provider.
79 bool from_keyword_provider_
;
81 AutocompleteMatchType::Type type_
;
83 // The relevance score.
87 // Whether this result's relevance score was fully or partly calculated
88 // based on server information, and thus is assumed to be more accurate.
89 // This is ultimately used in
90 // SearchProvider::ConvertResultsToAutocompleteMatches(), see comments
92 bool relevance_from_server_
;
94 // Optional deletion URL provided with suggestions. Fetching this URL
95 // should result in some reasonable deletion behaviour on the server,
96 // e.g. deleting this term out of a user's server-side search history.
97 std::string deletion_url_
;
100 class SuggestResult
: public Result
{
102 SuggestResult(const base::string16
& suggestion
,
103 AutocompleteMatchType::Type type
,
104 const base::string16
& match_contents
,
105 const base::string16
& match_contents_prefix
,
106 const base::string16
& annotation
,
107 const base::string16
& answer_contents
,
108 const base::string16
& answer_type
,
109 const std::string
& suggest_query_params
,
110 const std::string
& deletion_url
,
111 bool from_keyword_provider
,
113 bool relevance_from_server
,
114 bool should_prefetch
,
115 const base::string16
& input_text
);
116 virtual ~SuggestResult();
118 const base::string16
& suggestion() const { return suggestion_
; }
119 const base::string16
& match_contents_prefix() const {
120 return match_contents_prefix_
;
122 const base::string16
& annotation() const { return annotation_
; }
123 const std::string
& suggest_query_params() const {
124 return suggest_query_params_
;
127 const base::string16
& answer_contents() const { return answer_contents_
; }
128 const base::string16
& answer_type() const { return answer_type_
; }
130 bool should_prefetch() const { return should_prefetch_
; }
132 // Fills in |match_contents_class_| to reflect how |match_contents_| should
133 // be displayed and bolded against the current |input_text|. If
134 // |allow_bolding_all| is false and |match_contents_class_| would have all
135 // of |match_contents_| bolded, do nothing.
136 void ClassifyMatchContents(const bool allow_bolding_all
,
137 const base::string16
& input_text
);
140 virtual int CalculateRelevance(
141 const AutocompleteInput
& input
,
142 bool keyword_provider_requested
) const OVERRIDE
;
145 // The search terms to be used for this suggestion.
146 base::string16 suggestion_
;
148 // The contents to be displayed as prefix of match contents.
149 // Used for postfix suggestions to display a leading ellipsis (or some
150 // equivalent character) to indicate omitted text.
151 // Only used to pass this information to about:omnibox's "Additional Info".
152 base::string16 match_contents_prefix_
;
154 // Optional annotation for the |match_contents_| for disambiguation.
155 // This may be displayed in the autocomplete match contents, but is defined
156 // separately to facilitate different formatting.
157 base::string16 annotation_
;
159 // Optional additional parameters to be added to the search URL.
160 std::string suggest_query_params_
;
162 // Optional formatted Answers result.
163 base::string16 answer_contents_
;
165 // Type of optional formatted Answers result.
166 base::string16 answer_type_
;
168 // Should this result be prefetched?
169 bool should_prefetch_
;
172 class NavigationResult
: public Result
{
174 NavigationResult(const AutocompleteSchemeClassifier
& scheme_classifier
,
176 AutocompleteMatchType::Type type
,
177 const base::string16
& description
,
178 const std::string
& deletion_url
,
179 bool from_keyword_provider
,
181 bool relevance_from_server
,
182 const base::string16
& input_text
,
183 const std::string
& languages
);
184 virtual ~NavigationResult();
186 const GURL
& url() const { return url_
; }
187 const base::string16
& description() const { return description_
; }
188 const base::string16
& formatted_url() const { return formatted_url_
; }
190 // Fills in |match_contents_| and |match_contents_class_| to reflect how
191 // the URL should be displayed and bolded against the current |input_text|
192 // and user |languages|. If |allow_bolding_nothing| is false and
193 // |match_contents_class_| would result in an entirely unbolded
194 // |match_contents_|, do nothing.
195 void CalculateAndClassifyMatchContents(const bool allow_bolding_nothing
,
196 const base::string16
& input_text
,
197 const std::string
& languages
);
200 virtual int CalculateRelevance(
201 const AutocompleteInput
& input
,
202 bool keyword_provider_requested
) const OVERRIDE
;
205 // The suggested url for navigation.
208 // The properly formatted ("fixed up") URL string with equivalent meaning
209 // to the one in |url_|.
210 base::string16 formatted_url_
;
212 // The suggested navigational result description; generally the site name.
213 base::string16 description_
;
216 typedef std::vector
<SuggestResult
> SuggestResults
;
217 typedef std::vector
<NavigationResult
> NavigationResults
;
219 // A simple structure bundling most of the information (including
220 // both SuggestResults and NavigationResults) returned by a call to
221 // the suggest server.
223 // This has to be declared after the typedefs since it relies on some of them.
228 // Clears |suggest_results| and |navigation_results| and resets
229 // |verbatim_relevance| to -1 (implies unset).
232 // Returns whether any of the results (including verbatim) have
233 // server-provided scores.
234 bool HasServerProvidedScores() const;
236 // Query suggestions sorted by relevance score.
237 SuggestResults suggest_results
;
239 // Navigational suggestions sorted by relevance score.
240 NavigationResults navigation_results
;
242 // The server supplied verbatim relevance scores. Negative values
243 // indicate that there is no suggested score; a value of 0
244 // suppresses the verbatim result.
245 int verbatim_relevance
;
247 // The JSON metadata associated with this server response.
248 std::string metadata
;
250 // If the active suggest field trial (if any) has triggered.
251 bool field_trial_triggered
;
253 // If the relevance values of the results are from the server.
254 bool relevances_from_server
;
256 // URLs of any images in Answers results.
257 std::vector
<GURL
> answers_image_urls
;
260 DISALLOW_COPY_AND_ASSIGN(Results
);
263 // Extracts JSON data fetched by |source| and converts it to UTF-8.
264 static std::string
ExtractJsonData(const net::URLFetcher
* source
);
266 // Parses JSON response received from the provider, stripping XSSI
267 // protection if needed. Returns the parsed data if successful, NULL
269 static scoped_ptr
<base::Value
> DeserializeJsonData(std::string json_data
);
271 // Parses results from the suggest server and updates the appropriate suggest
272 // and navigation result lists in |results|. |is_keyword_result| indicates
273 // whether the response was received from the keyword provider.
274 // Returns whether the appropriate result list members were updated.
275 static bool ParseSuggestResults(
276 const base::Value
& root_val
,
277 const AutocompleteInput
& input
,
278 const AutocompleteSchemeClassifier
& scheme_classifier
,
279 int default_result_relevance
,
280 const std::string
& languages
,
281 bool is_keyword_result
,
285 FRIEND_TEST_ALL_PREFIXES(SearchSuggestionParser
,
286 GetAnswersImageURLsWithoutImagelines
);
287 FRIEND_TEST_ALL_PREFIXES(SearchSuggestionParser
,
288 GetAnswersImageURLsWithValidImage
);
290 // Gets URLs of any images in Answers results.
291 static void GetAnswersImageURLs(const base::DictionaryValue
* answer_json
,
292 std::vector
<GURL
>* urls
);
294 DISALLOW_COPY_AND_ASSIGN(SearchSuggestionParser
);
297 #endif // COMPONENTS_OMNIBOX_SEARCH_SUGGESTION_PARSER_H_