blob: 55932e03157b0cd2924170f66fbbb059c1818dc1 [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_
7#pragma once
8
9#include <vector>
10#include <string>
11
[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
21// AutocompleteMatch ----------------------------------------------------------
22
23// A single result line with classified spans. The autocomplete popup displays
24// the 'contents' and the 'description' (the description is optional) in the
25// autocomplete dropdown, and fills in 'fill_into_edit' into the textbox when
26// that line is selected. fill_into_edit may be the same as 'description' for
27// things like URLs, but may be different for searches or other providers. For
28// example, a search result may say "Search for asdf" as the description, but
29// "asdf" should appear in the box.
30struct AutocompleteMatch {
31 // Autocomplete matches contain strings that are classified according to a
32 // separate vector of styles. This vector associates flags with particular
33 // string segments, and must be in sorted order. All text must be associated
34 // with some kind of classification. Even if a match has no distinct
35 // segments, its vector should contain an entry at offset 0 with no flags.
36 //
37 // Example: The user typed "goog"
38 // http://www.google.com/ Google
39 // ^ ^ ^ ^ ^
40 // 0, | 15, | 4,
41 // 11,match 0,match
42 //
43 // This structure holds the classification information for each span.
44 struct ACMatchClassification {
45 // The values in here are not mutually exclusive -- use them like a
46 // bitfield. This also means we use "int" instead of this enum type when
47 // passing the values around, so the compiler doesn't complain.
48 enum Style {
49 NONE = 0,
50 URL = 1 << 0, // A URL
51 MATCH = 1 << 1, // A match for the user's search term
52 DIM = 1 << 2, // "Helper text"
53 };
54
55 ACMatchClassification(size_t offset, int style)
56 : offset(offset),
57 style(style) {
58 }
59
60 // Offset within the string that this classification starts
61 size_t offset;
62
63 int style;
64 };
65
66 typedef std::vector<ACMatchClassification> ACMatchClassifications;
67
68 // The type of this match.
69 enum Type {
70 URL_WHAT_YOU_TYPED = 0, // The input as a URL.
71 HISTORY_URL, // A past page whose URL contains the input.
72 HISTORY_TITLE, // A past page whose title contains the input.
73 HISTORY_BODY, // A past page whose body contains the input.
74 HISTORY_KEYWORD, // A past page whose keyword contains the input.
75 NAVSUGGEST, // A suggested URL.
76 SEARCH_WHAT_YOU_TYPED, // The input as a search query (with the default
77 // engine).
78 SEARCH_HISTORY, // A past search (with the default engine)
79 // containing the input.
80 SEARCH_SUGGEST, // A suggested search (with the default engine).
81 SEARCH_OTHER_ENGINE, // A search with a non-default engine.
[email protected]8f7405482011-04-13 11:08:5282 EXTENSION_APP, // An Extension App with a title/url that contains
83 // the input.
[email protected]9ac40092010-10-27 23:05:2684 NUM_TYPES,
85 };
86
[email protected]531e0342011-11-10 15:08:4187 // Null-terminated array of characters that are not valid within |contents|
88 // and |description| strings.
89 static const char16 kInvalidChars[];
90
[email protected]9ac40092010-10-27 23:05:2691 AutocompleteMatch();
92 AutocompleteMatch(AutocompleteProvider* provider,
93 int relevance,
94 bool deletable,
95 Type type);
[email protected]3cb0f8d92012-02-29 05:43:3496 AutocompleteMatch(const AutocompleteMatch& match);
[email protected]9ac40092010-10-27 23:05:2697 ~AutocompleteMatch();
98
[email protected]432954d02012-01-24 01:18:4399 // Converts |type| to a string representation. Used in logging and debugging.
[email protected]3cb0f8d92012-02-29 05:43:34100 AutocompleteMatch& operator=(const AutocompleteMatch& match);
101
102 // Converts |type| to a string representation. Used in logging.
[email protected]9ac40092010-10-27 23:05:26103 static std::string TypeToString(Type type);
104
105 // Converts |type| to a resource identifier for the appropriate icon for this
106 // type.
107 static int TypeToIcon(Type type);
108
109 // Comparison function for determining when one match is better than another.
110 static bool MoreRelevant(const AutocompleteMatch& elem1,
111 const AutocompleteMatch& elem2);
112
113 // Comparison functions for removing matches with duplicate destinations.
[email protected]3cb0f8d92012-02-29 05:43:34114 // Destinations are compared using |stripped_destination_url|.
[email protected]9ac40092010-10-27 23:05:26115 static bool DestinationSortFunc(const AutocompleteMatch& elem1,
116 const AutocompleteMatch& elem2);
117 static bool DestinationsEqual(const AutocompleteMatch& elem1,
118 const AutocompleteMatch& elem2);
119
120 // Helper functions for classes creating matches:
121 // Fills in the classifications for |text|, using |style| as the base style
122 // and marking the first instance of |find_text| as a match. (This match
123 // will also not be dimmed, if |style| has DIM set.)
[email protected]a2fedb1e2011-01-25 15:23:36124 static void ClassifyMatchInString(const string16& find_text,
125 const string16& text,
[email protected]9ac40092010-10-27 23:05:26126 int style,
127 ACMatchClassifications* classifications);
128
129 // Similar to ClassifyMatchInString(), but for cases where the range to mark
130 // as matching is already known (avoids calling find()). This can be helpful
131 // when find() would be misleading (e.g. you want to mark the second match in
132 // a string instead of the first).
133 static void ClassifyLocationInString(size_t match_location,
134 size_t match_length,
135 size_t overall_length,
136 int style,
137 ACMatchClassifications* classifications);
138
[email protected]9d2b5f3b2012-03-14 21:34:32139 // Converts classifications to and from a serialized string representation
140 // (using comma-separated integers to sequentially list positions and styles).
141 static std::string ClassificationsToString(
142 const ACMatchClassifications& classifications);
143 static ACMatchClassifications ClassificationsFromString(
144 const std::string& serialized_classifications);
145
146 // Adds a classification to the end of |classifications| iff its style is
147 // different from the last existing classification. |offset| must be larger
148 // than the offset of the last classification in |classifications|.
149 static void AddLastClassificationIfNecessary(
150 ACMatchClassifications* classifications,
151 size_t offset,
152 int style);
153
[email protected]531e0342011-11-10 15:08:41154 // Removes invalid characters from |text|. Should be called on strings coming
[email protected]5595f40d2011-10-28 17:29:18155 // from external sources (such as extensions) before assigning to |contents|
156 // or |description|.
157 static string16 SanitizeString(const string16& text);
158
[email protected]3cb0f8d92012-02-29 05:43:34159 // Copies the destination_url with "www." stripped off to
160 // |stripped_destination_url|. This method is invoked internally by the
161 // AutocompleteController and does not normally need to be invoked.
162 void ComputeStrippedDestinationURL();
163
[email protected]033f3422012-03-13 21:24:18164 // Gets data relevant to whether there should be any special keyword-related
165 // UI shown for this match. If this match represents a selected keyword, i.e.
166 // the UI should be "in keyword mode", |keyword| will be set to the keyword
167 // and |is_keyword_hint| will be set to false. If this match has a non-NULL
168 // |associated_keyword|, i.e. we should show a "Press [tab] to search ___"
169 // hint and allow the user to toggle into keyword mode, |keyword| will be set
170 // to the associated keyword and |is_keyword_hint| will be set to true. Note
171 // that only one of these states can be in effect at once. In all other
172 // cases, |keyword| will be cleared, even when our member variable |keyword|
[email protected]85b8d6f2012-05-08 20:53:47173 // is non-empty -- such as with non-substituting keywords or matches that
174 // represent searches using the default search engine. See also
175 // GetSubstitutingExplicitlyInvokedKeyword().
176 void GetKeywordUIState(Profile* profile,
177 string16* keyword,
[email protected]033f3422012-03-13 21:24:18178 bool* is_keyword_hint) const;
179
180 // Returns |keyword|, but only if it represents a substituting keyword that
181 // the user has explicitly invoked. If for example this match represents a
182 // search with the default search engine (and the user didn't explicitly
183 // invoke its keyword), this returns the empty string. The result is that
184 // this function returns a non-empty string in the same cases as when the UI
185 // should show up as being "in keyword mode".
[email protected]85b8d6f2012-05-08 20:53:47186 string16 GetSubstitutingExplicitlyInvokedKeyword(Profile* profile) const;
[email protected]033f3422012-03-13 21:24:18187
[email protected]85b8d6f2012-05-08 20:53:47188 // Returns the TemplateURL associated with this match. This may be NULL if
189 // the match has no keyword OR if the keyword no longer corresponds to a valid
190 // TemplateURL. See comments on |keyword| below.
191 TemplateURL* GetTemplateURL(Profile* profile) const;
[email protected]3cb0f8d92012-02-29 05:43:34192
[email protected]d1d0afe2010-12-16 18:04:52193 // The provider of this match, used to remember which provider the user had
[email protected]9ac40092010-10-27 23:05:26194 // selected when the input changes. This may be NULL, in which case there is
195 // no provider (or memory of the user's selection).
196 AutocompleteProvider* provider;
197
[email protected]ffc44872011-04-06 12:01:43198 // The relevance of this match. See table in autocomplete.h for scores
199 // returned by various providers. This is used to rank matches among all
200 // responding providers, so different providers must be carefully tuned to
201 // supply matches with appropriate relevance.
[email protected]9ac40092010-10-27 23:05:26202 //
[email protected]9ac40092010-10-27 23:05:26203 // TODO(pkasting): http://b/1111299 This should be calculated algorithmically,
204 // rather than being a fairly fixed value defined by the table above.
205 int relevance;
206
[email protected]cf6256f2012-06-12 23:36:01207 // How many times this result was typed in / selected from the omnibox.
208 // Only set for some providers and result_types. If it is not set,
209 // its value is -1. At the time of writing this comment, it is only
210 // set for matches from HistoryURL and HistoryQuickProvider.
211 int typed_count;
212
[email protected]9ac40092010-10-27 23:05:26213 // True if the user should be able to delete this match.
214 bool deletable;
215
216 // This string is loaded into the location bar when the item is selected
217 // by pressing the arrow keys. This may be different than a URL, for example,
218 // for search suggestions, this would just be the search terms.
[email protected]a2fedb1e2011-01-25 15:23:36219 string16 fill_into_edit;
[email protected]9ac40092010-10-27 23:05:26220
221 // The position within fill_into_edit from which we'll display the inline
[email protected]a2fedb1e2011-01-25 15:23:36222 // autocomplete string. This will be string16::npos if this match should
[email protected]9ac40092010-10-27 23:05:26223 // not be inline autocompleted.
224 size_t inline_autocomplete_offset;
225
226 // The URL to actually load when the autocomplete item is selected. This URL
227 // should be canonical so we can compare URLs with strcmp to avoid dupes.
228 // It may be empty if there is no possible navigation.
229 GURL destination_url;
230
[email protected]3cb0f8d92012-02-29 05:43:34231 // The destination URL with "www." stripped off for better dupe finding.
232 GURL stripped_destination_url;
233
[email protected]9ac40092010-10-27 23:05:26234 // The main text displayed in the address bar dropdown.
[email protected]a2fedb1e2011-01-25 15:23:36235 string16 contents;
[email protected]9ac40092010-10-27 23:05:26236 ACMatchClassifications contents_class;
237
238 // Additional helper text for each entry, such as a title or description.
[email protected]a2fedb1e2011-01-25 15:23:36239 string16 description;
[email protected]9ac40092010-10-27 23:05:26240 ACMatchClassifications description_class;
241
242 // The transition type to use when the user opens this match. By default
243 // this is TYPED. Providers whose matches do not look like URLs should set
244 // it to GENERATED.
[email protected]2905f742011-10-13 03:51:58245 content::PageTransition transition;
[email protected]9ac40092010-10-27 23:05:26246
247 // True when this match is the "what you typed" match from the history
248 // system.
249 bool is_history_what_you_typed_match;
250
251 // Type of this match.
252 Type type;
253
[email protected]3cb0f8d92012-02-29 05:43:34254 // Set with a keyword provider match if this match can show a keyword hint.
255 // For example, if this is a SearchProvider match for "www.amazon.com",
256 // |associated_keyword| could be a KeywordProvider match for "amazon.com".
257 scoped_ptr<AutocompleteMatch> associated_keyword;
258
[email protected]85b8d6f2012-05-08 20:53:47259 // The keyword of the TemplateURL the match originated from. This is nonempty
260 // for both explicit "keyword mode" matches as well as matches for the default
261 // search provider (so, any match for which we're doing substitution); it
262 // doesn't imply (alone) that the UI is going to show a keyword hint or
263 // keyword mode. For that, see GetKeywordUIState() or
264 // GetSubstitutingExplicitlyInvokedKeyword().
265 //
266 // CAUTION: The TemplateURL associated with this keyword may be deleted or
267 // modified while the AutocompleteMatch is alive. This means anyone who
268 // accesses it must perform any necessary sanity checks before blindly using
269 // it!
[email protected]3cb0f8d92012-02-29 05:43:34270 string16 keyword;
271
[email protected]9ac40092010-10-27 23:05:26272 // True if the user has starred the destination URL.
273 bool starred;
274
[email protected]7abfb3462011-01-31 16:43:06275 // True if this match is from a previous result.
276 bool from_previous;
277
[email protected]bca359b2012-06-24 07:53:04278 // Optional search terms args. If present,
279 // AutocompleteController::UpdateAssistedQueryStats() will incorporate this
280 // data with additional data it calculates and pass the completed struct to
281 // TemplateURLRef::ReplaceSearchTerms() to reset the match's |destination_url|
282 // after the complete set of matches in the AutocompleteResult has been chosen
283 // and sorted. Most providers will leave this as NULL, which will cause the
284 // AutocompleteController to do no additional transformations.
285 scoped_ptr<TemplateURLRef::SearchTermsArgs> search_terms_args;
286
[email protected]9ac40092010-10-27 23:05:26287#ifndef NDEBUG
288 // Does a data integrity check on this match.
289 void Validate() const;
290
291 // Checks one text/classifications pair for valid values.
292 void ValidateClassifications(
[email protected]a2fedb1e2011-01-25 15:23:36293 const string16& text,
[email protected]9ac40092010-10-27 23:05:26294 const ACMatchClassifications& classifications) const;
295#endif
296};
297
298typedef AutocompleteMatch::ACMatchClassification ACMatchClassification;
299typedef std::vector<ACMatchClassification> ACMatchClassifications;
300
301#endif // CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_MATCH_H_