blob: 3e7c208a69e1dae5fffcaecc9f98e6f7f17ff734 [file] [log] [blame]
[email protected]432954d02012-01-24 01:18:431// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]9ac40092010-10-27 23:05:262// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_MATCH_H_
6#define CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_MATCH_H_
[email protected]9ac40092010-10-27 23:05:267
[email protected]5281d422012-07-28 21:37:108#include <map>
[email protected]9ac40092010-10-27 23:05:269#include <string>
[email protected]bc7d0b52012-07-03 19:14:4010#include <vector>
[email protected]9ac40092010-10-27 23:05:2611
[email protected]3cb0f8d92012-02-29 05:43:3412#include "base/memory/scoped_ptr.h"
[email protected]bca359b2012-06-24 07:53:0413#include "chrome/browser/search_engines/template_url.h"
[email protected]2905f742011-10-13 03:51:5814#include "content/public/common/page_transition_types.h"
[email protected]9ac40092010-10-27 23:05:2615#include "googleurl/src/gurl.h"
16
17class AutocompleteProvider;
[email protected]85b8d6f2012-05-08 20:53:4718class Profile;
[email protected]9ac40092010-10-27 23:05:2619class TemplateURL;
20
[email protected]5281d422012-07-28 21:37:1021namespace base {
22class Time;
23} // namespace base
24
[email protected]9ac40092010-10-27 23:05:2625// AutocompleteMatch ----------------------------------------------------------
26
27// A single result line with classified spans. The autocomplete popup displays
28// the 'contents' and the 'description' (the description is optional) in the
29// autocomplete dropdown, and fills in 'fill_into_edit' into the textbox when
30// that line is selected. fill_into_edit may be the same as 'description' for
31// things like URLs, but may be different for searches or other providers. For
32// example, a search result may say "Search for asdf" as the description, but
33// "asdf" should appear in the box.
34struct AutocompleteMatch {
35 // Autocomplete matches contain strings that are classified according to a
36 // separate vector of styles. This vector associates flags with particular
37 // string segments, and must be in sorted order. All text must be associated
38 // with some kind of classification. Even if a match has no distinct
39 // segments, its vector should contain an entry at offset 0 with no flags.
40 //
41 // Example: The user typed "goog"
42 // http://www.google.com/ Google
43 // ^ ^ ^ ^ ^
44 // 0, | 15, | 4,
45 // 11,match 0,match
46 //
47 // This structure holds the classification information for each span.
48 struct ACMatchClassification {
49 // The values in here are not mutually exclusive -- use them like a
50 // bitfield. This also means we use "int" instead of this enum type when
51 // passing the values around, so the compiler doesn't complain.
52 enum Style {
53 NONE = 0,
54 URL = 1 << 0, // A URL
55 MATCH = 1 << 1, // A match for the user's search term
56 DIM = 1 << 2, // "Helper text"
57 };
58
59 ACMatchClassification(size_t offset, int style)
60 : offset(offset),
61 style(style) {
62 }
63
64 // Offset within the string that this classification starts
65 size_t offset;
66
67 int style;
68 };
69
70 typedef std::vector<ACMatchClassification> ACMatchClassifications;
71
[email protected]5281d422012-07-28 21:37:1072 // Type used by providers to attach additional, optional information to
73 // an AutocompleteMatch.
74 typedef std::map<std::string, std::string> AdditionalInfo;
75
[email protected]9ac40092010-10-27 23:05:2676 // The type of this match.
77 enum Type {
78 URL_WHAT_YOU_TYPED = 0, // The input as a URL.
79 HISTORY_URL, // A past page whose URL contains the input.
80 HISTORY_TITLE, // A past page whose title contains the input.
81 HISTORY_BODY, // A past page whose body contains the input.
82 HISTORY_KEYWORD, // A past page whose keyword contains the input.
83 NAVSUGGEST, // A suggested URL.
84 SEARCH_WHAT_YOU_TYPED, // The input as a search query (with the default
85 // engine).
86 SEARCH_HISTORY, // A past search (with the default engine)
87 // containing the input.
88 SEARCH_SUGGEST, // A suggested search (with the default engine).
89 SEARCH_OTHER_ENGINE, // A search with a non-default engine.
[email protected]8f7405482011-04-13 11:08:5290 EXTENSION_APP, // An Extension App with a title/url that contains
91 // the input.
[email protected]dbacefb2012-09-12 03:32:0692 CONTACT, // One of the user's contacts.
[email protected]25320602012-10-18 22:05:5693 BOOKMARK_TITLE, // A bookmark whose title contains the input.
[email protected]9ac40092010-10-27 23:05:2694 NUM_TYPES,
95 };
96
[email protected]531e0342011-11-10 15:08:4197 // Null-terminated array of characters that are not valid within |contents|
98 // and |description| strings.
99 static const char16 kInvalidChars[];
100
[email protected]9ac40092010-10-27 23:05:26101 AutocompleteMatch();
102 AutocompleteMatch(AutocompleteProvider* provider,
103 int relevance,
104 bool deletable,
105 Type type);
[email protected]3cb0f8d92012-02-29 05:43:34106 AutocompleteMatch(const AutocompleteMatch& match);
[email protected]9ac40092010-10-27 23:05:26107 ~AutocompleteMatch();
108
[email protected]432954d02012-01-24 01:18:43109 // Converts |type| to a string representation. Used in logging and debugging.
[email protected]3cb0f8d92012-02-29 05:43:34110 AutocompleteMatch& operator=(const AutocompleteMatch& match);
111
112 // Converts |type| to a string representation. Used in logging.
[email protected]9ac40092010-10-27 23:05:26113 static std::string TypeToString(Type type);
114
115 // Converts |type| to a resource identifier for the appropriate icon for this
[email protected]dd2f9e32012-09-19 14:23:40116 // type to show in the completion popup.
[email protected]9ac40092010-10-27 23:05:26117 static int TypeToIcon(Type type);
118
[email protected]dd2f9e32012-09-19 14:23:40119 // Converts |type| to a resource identifier for the appropriate icon for this
120 // type to show in the location bar.
121 static int TypeToLocationBarIcon(Type type);
122
[email protected]9ac40092010-10-27 23:05:26123 // Comparison function for determining when one match is better than another.
124 static bool MoreRelevant(const AutocompleteMatch& elem1,
125 const AutocompleteMatch& elem2);
126
127 // Comparison functions for removing matches with duplicate destinations.
[email protected]00193bf2012-09-15 14:52:50128 // Destinations are compared using |stripped_destination_url|. Pairs of
129 // matches with empty destinations are treated as differing, since empty
130 // destinations are expected for non-navigable matches.
[email protected]9ac40092010-10-27 23:05:26131 static bool DestinationSortFunc(const AutocompleteMatch& elem1,
132 const AutocompleteMatch& elem2);
133 static bool DestinationsEqual(const AutocompleteMatch& elem1,
134 const AutocompleteMatch& elem2);
135
136 // Helper functions for classes creating matches:
137 // Fills in the classifications for |text|, using |style| as the base style
138 // and marking the first instance of |find_text| as a match. (This match
139 // will also not be dimmed, if |style| has DIM set.)
[email protected]a2fedb1e2011-01-25 15:23:36140 static void ClassifyMatchInString(const string16& find_text,
141 const string16& text,
[email protected]9ac40092010-10-27 23:05:26142 int style,
143 ACMatchClassifications* classifications);
144
145 // Similar to ClassifyMatchInString(), but for cases where the range to mark
146 // as matching is already known (avoids calling find()). This can be helpful
147 // when find() would be misleading (e.g. you want to mark the second match in
148 // a string instead of the first).
149 static void ClassifyLocationInString(size_t match_location,
150 size_t match_length,
151 size_t overall_length,
152 int style,
153 ACMatchClassifications* classifications);
154
[email protected]3b81314d2012-09-11 02:48:41155 // Returns a new vector of classifications containing the merged contents of
156 // |classifications1| and |classifications2|.
157 static ACMatchClassifications MergeClassifications(
158 const ACMatchClassifications& classifications1,
159 const ACMatchClassifications& classifications2);
160
[email protected]9d2b5f3b2012-03-14 21:34:32161 // Converts classifications to and from a serialized string representation
162 // (using comma-separated integers to sequentially list positions and styles).
163 static std::string ClassificationsToString(
164 const ACMatchClassifications& classifications);
165 static ACMatchClassifications ClassificationsFromString(
166 const std::string& serialized_classifications);
167
168 // Adds a classification to the end of |classifications| iff its style is
169 // different from the last existing classification. |offset| must be larger
170 // than the offset of the last classification in |classifications|.
171 static void AddLastClassificationIfNecessary(
172 ACMatchClassifications* classifications,
173 size_t offset,
174 int style);
175
[email protected]531e0342011-11-10 15:08:41176 // Removes invalid characters from |text|. Should be called on strings coming
[email protected]5595f40d2011-10-28 17:29:18177 // from external sources (such as extensions) before assigning to |contents|
178 // or |description|.
179 static string16 SanitizeString(const string16& text);
180
[email protected]749e7ae02012-09-05 18:47:46181 // Convenience function to check if |type| is a search (as opposed to a URL or
182 // an extension).
183 static bool IsSearchType(Type type);
184
[email protected]3cb0f8d92012-02-29 05:43:34185 // Copies the destination_url with "www." stripped off to
[email protected]345e8fda2012-09-06 01:07:47186 // |stripped_destination_url| and also converts https protocol to
187 // http. These two conversions are merely to allow comparisons to
188 // remove likely duplicates; these URLs are not used as actual
189 // destination URLs. This method is invoked internally by the
[email protected]00193bf2012-09-15 14:52:50190 // AutocompleteResult and does not normally need to be invoked.
[email protected]dbff446582012-10-30 00:20:26191 // If |profile| is not NULL, it is used to get a template URL corresponding
192 // to this match. The template is used to strip off query args other than
193 // the search terms themselves that would otherwise prevent from proper
194 // deduping.
195 void ComputeStrippedDestinationURL(Profile* profile);
[email protected]3cb0f8d92012-02-29 05:43:34196
[email protected]033f3422012-03-13 21:24:18197 // Gets data relevant to whether there should be any special keyword-related
198 // UI shown for this match. If this match represents a selected keyword, i.e.
199 // the UI should be "in keyword mode", |keyword| will be set to the keyword
200 // and |is_keyword_hint| will be set to false. If this match has a non-NULL
201 // |associated_keyword|, i.e. we should show a "Press [tab] to search ___"
202 // hint and allow the user to toggle into keyword mode, |keyword| will be set
203 // to the associated keyword and |is_keyword_hint| will be set to true. Note
204 // that only one of these states can be in effect at once. In all other
205 // cases, |keyword| will be cleared, even when our member variable |keyword|
[email protected]85b8d6f2012-05-08 20:53:47206 // is non-empty -- such as with non-substituting keywords or matches that
207 // represent searches using the default search engine. See also
208 // GetSubstitutingExplicitlyInvokedKeyword().
209 void GetKeywordUIState(Profile* profile,
210 string16* keyword,
[email protected]033f3422012-03-13 21:24:18211 bool* is_keyword_hint) const;
212
213 // Returns |keyword|, but only if it represents a substituting keyword that
214 // the user has explicitly invoked. If for example this match represents a
215 // search with the default search engine (and the user didn't explicitly
216 // invoke its keyword), this returns the empty string. The result is that
217 // this function returns a non-empty string in the same cases as when the UI
218 // should show up as being "in keyword mode".
[email protected]85b8d6f2012-05-08 20:53:47219 string16 GetSubstitutingExplicitlyInvokedKeyword(Profile* profile) const;
[email protected]033f3422012-03-13 21:24:18220
[email protected]85b8d6f2012-05-08 20:53:47221 // Returns the TemplateURL associated with this match. This may be NULL if
222 // the match has no keyword OR if the keyword no longer corresponds to a valid
223 // TemplateURL. See comments on |keyword| below.
[email protected]dbff446582012-10-30 00:20:26224 // If |allow_fallback_to_destination_host| is true and the keyword does
225 // not map to a valid TemplateURL, we'll then check for a TemplateURL that
226 // corresponds to the destination_url's hostname.
227 TemplateURL* GetTemplateURL(Profile* profile,
228 bool allow_fallback_to_destination_host) const;
[email protected]3cb0f8d92012-02-29 05:43:34229
[email protected]5281d422012-07-28 21:37:10230 // Adds optional information to the |additional_info| dictionary.
231 void RecordAdditionalInfo(const std::string& property,
232 const std::string& value);
233 void RecordAdditionalInfo(const std::string& property, int value);
234 void RecordAdditionalInfo(const std::string& property,
235 const base::Time& value);
236
[email protected]d1d0afe2010-12-16 18:04:52237 // The provider of this match, used to remember which provider the user had
[email protected]9ac40092010-10-27 23:05:26238 // selected when the input changes. This may be NULL, in which case there is
239 // no provider (or memory of the user's selection).
240 AutocompleteProvider* provider;
241
[email protected]ffc44872011-04-06 12:01:43242 // The relevance of this match. See table in autocomplete.h for scores
243 // returned by various providers. This is used to rank matches among all
244 // responding providers, so different providers must be carefully tuned to
245 // supply matches with appropriate relevance.
[email protected]9ac40092010-10-27 23:05:26246 //
[email protected]9ac40092010-10-27 23:05:26247 // TODO(pkasting): http://b/1111299 This should be calculated algorithmically,
248 // rather than being a fairly fixed value defined by the table above.
249 int relevance;
250
[email protected]cf6256f2012-06-12 23:36:01251 // How many times this result was typed in / selected from the omnibox.
252 // Only set for some providers and result_types. If it is not set,
253 // its value is -1. At the time of writing this comment, it is only
254 // set for matches from HistoryURL and HistoryQuickProvider.
255 int typed_count;
256
[email protected]9ac40092010-10-27 23:05:26257 // True if the user should be able to delete this match.
258 bool deletable;
259
260 // This string is loaded into the location bar when the item is selected
261 // by pressing the arrow keys. This may be different than a URL, for example,
262 // for search suggestions, this would just be the search terms.
[email protected]a2fedb1e2011-01-25 15:23:36263 string16 fill_into_edit;
[email protected]9ac40092010-10-27 23:05:26264
265 // The position within fill_into_edit from which we'll display the inline
[email protected]a2fedb1e2011-01-25 15:23:36266 // autocomplete string. This will be string16::npos if this match should
[email protected]9ac40092010-10-27 23:05:26267 // not be inline autocompleted.
268 size_t inline_autocomplete_offset;
269
270 // The URL to actually load when the autocomplete item is selected. This URL
271 // should be canonical so we can compare URLs with strcmp to avoid dupes.
272 // It may be empty if there is no possible navigation.
273 GURL destination_url;
274
[email protected]3cb0f8d92012-02-29 05:43:34275 // The destination URL with "www." stripped off for better dupe finding.
276 GURL stripped_destination_url;
277
[email protected]9ac40092010-10-27 23:05:26278 // The main text displayed in the address bar dropdown.
[email protected]a2fedb1e2011-01-25 15:23:36279 string16 contents;
[email protected]9ac40092010-10-27 23:05:26280 ACMatchClassifications contents_class;
281
282 // Additional helper text for each entry, such as a title or description.
[email protected]a2fedb1e2011-01-25 15:23:36283 string16 description;
[email protected]9ac40092010-10-27 23:05:26284 ACMatchClassifications description_class;
285
286 // The transition type to use when the user opens this match. By default
287 // this is TYPED. Providers whose matches do not look like URLs should set
288 // it to GENERATED.
[email protected]2905f742011-10-13 03:51:58289 content::PageTransition transition;
[email protected]9ac40092010-10-27 23:05:26290
291 // True when this match is the "what you typed" match from the history
292 // system.
293 bool is_history_what_you_typed_match;
294
295 // Type of this match.
296 Type type;
297
[email protected]3cb0f8d92012-02-29 05:43:34298 // Set with a keyword provider match if this match can show a keyword hint.
299 // For example, if this is a SearchProvider match for "www.amazon.com",
300 // |associated_keyword| could be a KeywordProvider match for "amazon.com".
301 scoped_ptr<AutocompleteMatch> associated_keyword;
302
[email protected]85b8d6f2012-05-08 20:53:47303 // The keyword of the TemplateURL the match originated from. This is nonempty
304 // for both explicit "keyword mode" matches as well as matches for the default
305 // search provider (so, any match for which we're doing substitution); it
306 // doesn't imply (alone) that the UI is going to show a keyword hint or
307 // keyword mode. For that, see GetKeywordUIState() or
308 // GetSubstitutingExplicitlyInvokedKeyword().
309 //
310 // CAUTION: The TemplateURL associated with this keyword may be deleted or
311 // modified while the AutocompleteMatch is alive. This means anyone who
312 // accesses it must perform any necessary sanity checks before blindly using
313 // it!
[email protected]3cb0f8d92012-02-29 05:43:34314 string16 keyword;
315
[email protected]9ac40092010-10-27 23:05:26316 // True if the user has starred the destination URL.
317 bool starred;
318
[email protected]7abfb3462011-01-31 16:43:06319 // True if this match is from a previous result.
320 bool from_previous;
321
[email protected]bca359b2012-06-24 07:53:04322 // Optional search terms args. If present,
323 // AutocompleteController::UpdateAssistedQueryStats() will incorporate this
324 // data with additional data it calculates and pass the completed struct to
325 // TemplateURLRef::ReplaceSearchTerms() to reset the match's |destination_url|
326 // after the complete set of matches in the AutocompleteResult has been chosen
327 // and sorted. Most providers will leave this as NULL, which will cause the
328 // AutocompleteController to do no additional transformations.
329 scoped_ptr<TemplateURLRef::SearchTermsArgs> search_terms_args;
330
[email protected]5281d422012-07-28 21:37:10331 // Information dictionary into which each provider can optionally record a
332 // property and associated value and which is presented in chrome://omnibox.
333 AdditionalInfo additional_info;
334
[email protected]9ac40092010-10-27 23:05:26335#ifndef NDEBUG
336 // Does a data integrity check on this match.
337 void Validate() const;
338
339 // Checks one text/classifications pair for valid values.
340 void ValidateClassifications(
[email protected]a2fedb1e2011-01-25 15:23:36341 const string16& text,
[email protected]9ac40092010-10-27 23:05:26342 const ACMatchClassifications& classifications) const;
343#endif
344};
345
346typedef AutocompleteMatch::ACMatchClassification ACMatchClassification;
347typedef std::vector<ACMatchClassification> ACMatchClassifications;
[email protected]bc7d0b52012-07-03 19:14:40348typedef std::vector<AutocompleteMatch> ACMatches;
[email protected]9ac40092010-10-27 23:05:26349
350#endif // CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_MATCH_H_