Convert events_unittests to run exclusively on Swarming
[chromium-blink-merge.git] / components / omnibox / autocomplete_match.h
blobfc460dcfd37e5ad3eba49a44048b2854ce704d3f
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_AUTOCOMPLETE_MATCH_H_
6 #define COMPONENTS_OMNIBOX_AUTOCOMPLETE_MATCH_H_
8 #include <map>
9 #include <string>
10 #include <vector>
12 #include "base/memory/scoped_ptr.h"
13 #include "components/omnibox/autocomplete_input.h"
14 #include "components/omnibox/autocomplete_match_type.h"
15 #include "components/search_engines/template_url.h"
16 #include "ui/base/page_transition_types.h"
17 #include "url/gurl.h"
19 class AutocompleteProvider;
20 class SuggestionAnswer;
21 class TemplateURL;
22 class TemplateURLService;
24 namespace base {
25 class Time;
26 } // namespace base
28 const char kACMatchPropertyInputText[] = "input text";
29 const char kACMatchPropertyContentsPrefix[] = "match contents prefix";
30 const char kACMatchPropertyContentsStartIndex[] = "match contents start index";
32 // AutocompleteMatch ----------------------------------------------------------
34 // A single result line with classified spans. The autocomplete popup displays
35 // the 'contents' and the 'description' (the description is optional) in the
36 // autocomplete dropdown, and fills in 'fill_into_edit' into the textbox when
37 // that line is selected. fill_into_edit may be the same as 'description' for
38 // things like URLs, but may be different for searches or other providers. For
39 // example, a search result may say "Search for asdf" as the description, but
40 // "asdf" should appear in the box.
41 struct AutocompleteMatch {
42 // Autocomplete matches contain strings that are classified according to a
43 // separate vector of styles. This vector associates flags with particular
44 // string segments, and must be in sorted order. All text must be associated
45 // with some kind of classification. Even if a match has no distinct
46 // segments, its vector should contain an entry at offset 0 with no flags.
48 // Example: The user typed "goog"
49 // http://www.google.com/ Google
50 // ^ ^ ^ ^ ^
51 // 0, | 15, | 4,
52 // 11,match 0,match
54 // This structure holds the classification information for each span.
55 struct ACMatchClassification {
56 // The values in here are not mutually exclusive -- use them like a
57 // bitfield. This also means we use "int" instead of this enum type when
58 // passing the values around, so the compiler doesn't complain.
59 enum Style {
60 NONE = 0,
61 URL = 1 << 0, // A URL
62 MATCH = 1 << 1, // A match for the user's search term
63 DIM = 1 << 2, // "Helper text"
66 ACMatchClassification(size_t offset, int style)
67 : offset(offset),
68 style(style) {
71 // Offset within the string that this classification starts
72 size_t offset;
74 int style;
77 typedef std::vector<ACMatchClassification> ACMatchClassifications;
79 // Type used by providers to attach additional, optional information to
80 // an AutocompleteMatch.
81 typedef std::map<std::string, std::string> AdditionalInfo;
83 // The type of this match.
84 typedef AutocompleteMatchType::Type Type;
86 // Null-terminated array of characters that are not valid within |contents|
87 // and |description| strings.
88 static const base::char16 kInvalidChars[];
90 AutocompleteMatch();
91 AutocompleteMatch(AutocompleteProvider* provider,
92 int relevance,
93 bool deletable,
94 Type type);
95 AutocompleteMatch(const AutocompleteMatch& match);
96 ~AutocompleteMatch();
98 // Converts |type| to a string representation. Used in logging and debugging.
99 AutocompleteMatch& operator=(const AutocompleteMatch& match);
101 // Converts |type| to a resource identifier for the appropriate icon for this
102 // type to show in the completion popup.
103 static int TypeToIcon(Type type);
105 // Comparison function for determining when one match is better than another.
106 static bool MoreRelevant(const AutocompleteMatch& elem1,
107 const AutocompleteMatch& elem2);
109 // Comparison function for removing matches with duplicate destinations.
110 // Destinations are compared using |stripped_destination_url|. Pairs of
111 // matches with empty destinations are treated as differing, since empty
112 // destinations are expected for non-navigable matches.
113 static bool DestinationsEqual(const AutocompleteMatch& elem1,
114 const AutocompleteMatch& elem2);
116 // Helper functions for classes creating matches:
117 // Fills in the classifications for |text|, using |style| as the base style
118 // and marking the first instance of |find_text| as a match. (This match
119 // will also not be dimmed, if |style| has DIM set.)
120 static void ClassifyMatchInString(const base::string16& find_text,
121 const base::string16& text,
122 int style,
123 ACMatchClassifications* classifications);
125 // Similar to ClassifyMatchInString(), but for cases where the range to mark
126 // as matching is already known (avoids calling find()). This can be helpful
127 // when find() would be misleading (e.g. you want to mark the second match in
128 // a string instead of the first).
129 static void ClassifyLocationInString(size_t match_location,
130 size_t match_length,
131 size_t overall_length,
132 int style,
133 ACMatchClassifications* classifications);
135 // Returns a new vector of classifications containing the merged contents of
136 // |classifications1| and |classifications2|.
137 static ACMatchClassifications MergeClassifications(
138 const ACMatchClassifications& classifications1,
139 const ACMatchClassifications& classifications2);
141 // Converts classifications to and from a serialized string representation
142 // (using comma-separated integers to sequentially list positions and styles).
143 static std::string ClassificationsToString(
144 const ACMatchClassifications& classifications);
145 static ACMatchClassifications ClassificationsFromString(
146 const std::string& serialized_classifications);
148 // Adds a classification to the end of |classifications| iff its style is
149 // different from the last existing classification. |offset| must be larger
150 // than the offset of the last classification in |classifications|.
151 static void AddLastClassificationIfNecessary(
152 ACMatchClassifications* classifications,
153 size_t offset,
154 int style);
156 // Returns true if at least one style in |classifications| is of type MATCH.
157 static bool HasMatchStyle(const ACMatchClassifications& classifications);
159 // Removes invalid characters from |text|. Should be called on strings coming
160 // from external sources (such as extensions) before assigning to |contents|
161 // or |description|.
162 static base::string16 SanitizeString(const base::string16& text);
164 // Convenience function to check if |type| is a search (as opposed to a URL or
165 // an extension).
166 static bool IsSearchType(Type type);
168 // Convenience function to check if |type| is a special search suggest type -
169 // like entity, personalized, profile or postfix.
170 static bool IsSpecializedSearchType(Type type);
172 // A static version GetTemplateURL() that takes the match's keyword and
173 // match's hostname as parameters. In short, returns the TemplateURL
174 // associated with |keyword| if it exists; otherwise returns the TemplateURL
175 // associated with |host| if it exists.
176 static TemplateURL* GetTemplateURLWithKeyword(
177 TemplateURLService* template_url_service,
178 const base::string16& keyword,
179 const std::string& host);
181 // Returns |url| altered by stripping off "www.", converting https protocol
182 // to http, and stripping excess query parameters. These conversions are
183 // merely to allow comparisons to remove likely duplicates; these URLs are
184 // not used as actual destination URLs. If |template_url_service| is not
185 // NULL, it is used to get a template URL corresponding to this match. If
186 // the match's keyword is known, it can be passed in. Otherwise, it can be
187 // left empty and the template URL (if any) is determined from the
188 // destination's hostname. The template URL is used to strip off query args
189 // other than the search terms themselves that would otherwise prevent doing
190 // proper deduping.
191 static GURL GURLToStrippedGURL(const GURL& url,
192 TemplateURLService* template_url_service,
193 const base::string16& keyword);
195 // Computes the stripped destination URL (via GURLToStrippedGURL()) and
196 // stores the result in |stripped_destination_url|.
197 void ComputeStrippedDestinationURL(TemplateURLService* template_url_service);
199 // Sets |allowed_to_be_default_match| to true if this match is effectively
200 // the URL-what-you-typed match (i.e., would be dupped against the UWYT
201 // match when AutocompleteResult merges matches). |canonical_input_url| is
202 // the AutocompleteInput interpreted as a URL (i.e.,
203 // AutocompleteInput::canonicalized_url()).
204 void EnsureUWYTIsAllowedToBeDefault(const GURL& canonical_input_url,
205 TemplateURLService* template_url_service);
207 // Gets data relevant to whether there should be any special keyword-related
208 // UI shown for this match. If this match represents a selected keyword, i.e.
209 // the UI should be "in keyword mode", |keyword| will be set to the keyword
210 // and |is_keyword_hint| will be set to false. If this match has a non-NULL
211 // |associated_keyword|, i.e. we should show a "Press [tab] to search ___"
212 // hint and allow the user to toggle into keyword mode, |keyword| will be set
213 // to the associated keyword and |is_keyword_hint| will be set to true. Note
214 // that only one of these states can be in effect at once. In all other
215 // cases, |keyword| will be cleared, even when our member variable |keyword|
216 // is non-empty -- such as with non-substituting keywords or matches that
217 // represent searches using the default search engine. See also
218 // GetSubstitutingExplicitlyInvokedKeyword().
219 void GetKeywordUIState(TemplateURLService* template_url_service,
220 base::string16* keyword,
221 bool* is_keyword_hint) const;
223 // Returns |keyword|, but only if it represents a substituting keyword that
224 // the user has explicitly invoked. If for example this match represents a
225 // search with the default search engine (and the user didn't explicitly
226 // invoke its keyword), this returns the empty string. The result is that
227 // this function returns a non-empty string in the same cases as when the UI
228 // should show up as being "in keyword mode".
229 base::string16 GetSubstitutingExplicitlyInvokedKeyword(
230 TemplateURLService* template_url_service) const;
232 // Returns the TemplateURL associated with this match. This may be NULL if
233 // the match has no keyword OR if the keyword no longer corresponds to a valid
234 // TemplateURL. See comments on |keyword| below.
235 // If |allow_fallback_to_destination_host| is true and the keyword does
236 // not map to a valid TemplateURL, we'll then check for a TemplateURL that
237 // corresponds to the destination_url's hostname.
238 TemplateURL* GetTemplateURL(TemplateURLService* template_url_service,
239 bool allow_fallback_to_destination_host) const;
241 // Adds optional information to the |additional_info| dictionary.
242 void RecordAdditionalInfo(const std::string& property,
243 const std::string& value);
244 void RecordAdditionalInfo(const std::string& property, int value);
245 void RecordAdditionalInfo(const std::string& property,
246 const base::Time& value);
248 // Returns the value recorded for |property| in the |additional_info|
249 // dictionary. Returns the empty string if no such value exists.
250 std::string GetAdditionalInfo(const std::string& property) const;
252 // Returns whether this match is a "verbatim" match: a URL navigation directly
253 // to the user's input, a search for the user's input with the default search
254 // engine, or a "keyword mode" search for the query portion of the user's
255 // input. Note that rare or unusual types that could be considered verbatim,
256 // such as keyword engine matches or extension-provided matches, aren't
257 // detected by this IsVerbatimType, as the user will not be able to infer
258 // what will happen when he or she presses enter in those cases if the match
259 // is not shown.
260 bool IsVerbatimType() const;
262 // Returns whether this match or any duplicate of this match can be deleted.
263 // This is used to decide whether we should call DeleteMatch().
264 bool SupportsDeletion() const;
266 // Swaps the contents and description fields, and their associated
267 // classifications, if this is a match for which we should emphasize the
268 // title (stored in the description field) over the URL (in the contents
269 // field). Intended to only be used at the UI level before displaying, lest
270 // other omnibox systems get confused about which is which. See the code
271 // that sets |swap_contents_and_description| for conditions under which
272 // it is true.
273 void PossiblySwapContentsAndDescriptionForDisplay();
275 // The provider of this match, used to remember which provider the user had
276 // selected when the input changes. This may be NULL, in which case there is
277 // no provider (or memory of the user's selection).
278 AutocompleteProvider* provider;
280 // The relevance of this match. See table in autocomplete.h for scores
281 // returned by various providers. This is used to rank matches among all
282 // responding providers, so different providers must be carefully tuned to
283 // supply matches with appropriate relevance.
285 // TODO(pkasting): http://b/1111299 This should be calculated algorithmically,
286 // rather than being a fairly fixed value defined by the table above.
287 int relevance;
289 // How many times this result was typed in / selected from the omnibox.
290 // Only set for some providers and result_types. If it is not set,
291 // its value is -1. At the time of writing this comment, it is only
292 // set for matches from HistoryURL and HistoryQuickProvider.
293 int typed_count;
295 // True if the user should be able to delete this match.
296 bool deletable;
298 // This string is loaded into the location bar when the item is selected
299 // by pressing the arrow keys. This may be different than a URL, for example,
300 // for search suggestions, this would just be the search terms.
301 base::string16 fill_into_edit;
303 // The inline autocompletion to display after the user's typing in the
304 // omnibox, if this match becomes the default match. It may be empty.
305 base::string16 inline_autocompletion;
307 // If false, the omnibox should prevent this match from being the
308 // default match. Providers should set this to true only if the
309 // user's input, plus any inline autocompletion on this match, would
310 // lead the user to expect a navigation to this match's destination.
311 // For example, with input "foo", a search for "bar" or navigation
312 // to "bar.com" should not set this flag; a navigation to "foo.com"
313 // should only set this flag if ".com" will be inline autocompleted;
314 // and a navigation to "foo/" (an intranet host) or search for "foo"
315 // should set this flag.
316 bool allowed_to_be_default_match;
318 // The URL to actually load when the autocomplete item is selected. This URL
319 // should be canonical so we can compare URLs with strcmp to avoid dupes.
320 // It may be empty if there is no possible navigation.
321 GURL destination_url;
323 // The destination URL with "www." stripped off for better dupe finding.
324 GURL stripped_destination_url;
326 // The main text displayed in the address bar dropdown.
327 base::string16 contents;
328 ACMatchClassifications contents_class;
330 // Additional helper text for each entry, such as a title or description.
331 base::string16 description;
332 ACMatchClassifications description_class;
334 // If true, UI-level code should swap the contents and description fields
335 // before displaying.
336 bool swap_contents_and_description;
338 // TODO(jdonnelly): Remove the first two properties once the downstream
339 // clients are using the SuggestionAnswer.
340 // A rich-format version of the display for the dropdown.
341 base::string16 answer_contents;
342 base::string16 answer_type;
343 scoped_ptr<SuggestionAnswer> answer;
345 // The transition type to use when the user opens this match. By default
346 // this is TYPED. Providers whose matches do not look like URLs should set
347 // it to GENERATED.
348 ui::PageTransition transition;
350 // Type of this match.
351 Type type;
353 // Set with a keyword provider match if this match can show a keyword hint.
354 // For example, if this is a SearchProvider match for "www.amazon.com",
355 // |associated_keyword| could be a KeywordProvider match for "amazon.com".
357 // When this is set, the popup will show a ">" symbol at the right edge of the
358 // line for this match, and tab/shift-tab will toggle in and out of keyword
359 // mode without disturbing the rest of the popup. See also
360 // OmniboxPopupModel::SetSelectedLineState().
361 scoped_ptr<AutocompleteMatch> associated_keyword;
363 // The keyword of the TemplateURL the match originated from. This is nonempty
364 // for both explicit "keyword mode" matches as well as matches for the default
365 // search provider (so, any match for which we're doing substitution); it
366 // doesn't imply (alone) that the UI is going to show a keyword hint or
367 // keyword mode. For that, see GetKeywordUIState() or
368 // GetSubstitutingExplicitlyInvokedKeyword().
370 // CAUTION: The TemplateURL associated with this keyword may be deleted or
371 // modified while the AutocompleteMatch is alive. This means anyone who
372 // accesses it must perform any necessary sanity checks before blindly using
373 // it!
374 base::string16 keyword;
376 // True if this match is from a previous result.
377 bool from_previous;
379 // Optional search terms args. If present,
380 // AutocompleteController::UpdateAssistedQueryStats() will incorporate this
381 // data with additional data it calculates and pass the completed struct to
382 // TemplateURLRef::ReplaceSearchTerms() to reset the match's |destination_url|
383 // after the complete set of matches in the AutocompleteResult has been chosen
384 // and sorted. Most providers will leave this as NULL, which will cause the
385 // AutocompleteController to do no additional transformations.
386 scoped_ptr<TemplateURLRef::SearchTermsArgs> search_terms_args;
388 // Information dictionary into which each provider can optionally record a
389 // property and associated value and which is presented in chrome://omnibox.
390 AdditionalInfo additional_info;
392 // A list of matches culled during de-duplication process, retained to
393 // ensure if a match is deleted, the duplicates are deleted as well.
394 std::vector<AutocompleteMatch> duplicate_matches;
396 #ifndef NDEBUG
397 // Does a data integrity check on this match.
398 void Validate() const;
400 // Checks one text/classifications pair for valid values.
401 void ValidateClassifications(
402 const base::string16& text,
403 const ACMatchClassifications& classifications) const;
404 #endif
407 typedef AutocompleteMatch::ACMatchClassification ACMatchClassification;
408 typedef std::vector<ACMatchClassification> ACMatchClassifications;
409 typedef std::vector<AutocompleteMatch> ACMatches;
411 #endif // COMPONENTS_OMNIBOX_AUTOCOMPLETE_MATCH_H_