OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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. | |
4 | |
5 #ifndef CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_RESULT_H_ | |
6 #define CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_RESULT_H_ | |
7 | |
8 #include <stddef.h> | |
9 | |
10 #include <map> | |
11 | |
12 #include "base/basictypes.h" | |
13 #include "components/metrics/proto/omnibox_event.pb.h" | |
14 #include "components/omnibox/autocomplete_match.h" | |
15 #include "url/gurl.h" | |
16 | |
17 class AutocompleteInput; | |
18 class AutocompleteProvider; | |
19 class TemplateURLService; | |
20 | |
21 // All matches from all providers for a particular query. This also tracks | |
22 // what the default match should be if the user doesn't manually select another | |
23 // match. | |
24 class AutocompleteResult { | |
25 public: | |
26 typedef ACMatches::const_iterator const_iterator; | |
27 typedef ACMatches::iterator iterator; | |
28 | |
29 // The "Selection" struct is the information we need to select the same match | |
30 // in one result set that was selected in another. | |
31 struct Selection { | |
32 Selection() | |
33 : provider_affinity(NULL), | |
34 is_history_what_you_typed_match(false) { | |
35 } | |
36 | |
37 // Clear the selection entirely. | |
38 void Clear(); | |
39 | |
40 // True when the selection is empty. | |
41 bool empty() const { | |
42 return destination_url.is_empty() && !provider_affinity && | |
43 !is_history_what_you_typed_match; | |
44 } | |
45 | |
46 // The desired destination URL. | |
47 GURL destination_url; | |
48 | |
49 // The desired provider. If we can't find a match with the specified | |
50 // |destination_url|, we'll use the best match from this provider. | |
51 const AutocompleteProvider* provider_affinity; | |
52 | |
53 // True when this is the HistoryURLProvider's "what you typed" match. This | |
54 // can't be tracked using |destination_url| because its URL changes on every | |
55 // keystroke, so if this is set, we'll preserve the selection by simply | |
56 // choosing the new "what you typed" entry and ignoring |destination_url|. | |
57 bool is_history_what_you_typed_match; | |
58 }; | |
59 | |
60 // Max number of matches we'll show from the various providers. | |
61 static const size_t kMaxMatches; | |
62 | |
63 AutocompleteResult(); | |
64 ~AutocompleteResult(); | |
65 | |
66 // Copies matches from |old_matches| to provide a consistant result set. See | |
67 // comments in code for specifics. | |
68 void CopyOldMatches(const AutocompleteInput& input, | |
69 const AutocompleteResult& old_matches, | |
70 TemplateURLService* template_url_service); | |
71 | |
72 // Adds a new set of matches to the result set. Does not re-sort. | |
73 void AppendMatches(const ACMatches& matches); | |
74 | |
75 // Removes duplicates, puts the list in sorted order and culls to leave only | |
76 // the best kMaxMatches matches. Sets the default match to the best match | |
77 // and updates the alternate nav URL. | |
78 void SortAndCull(const AutocompleteInput& input, | |
79 TemplateURLService* template_url_service); | |
80 | |
81 // Returns true if at least one match was copied from the last result. | |
82 bool HasCopiedMatches() const; | |
83 | |
84 // Vector-style accessors/operators. | |
85 size_t size() const; | |
86 bool empty() const; | |
87 const_iterator begin() const; | |
88 iterator begin(); | |
89 const_iterator end() const; | |
90 iterator end(); | |
91 | |
92 // Returns the match at the given index. | |
93 const AutocompleteMatch& match_at(size_t index) const; | |
94 AutocompleteMatch* match_at(size_t index); | |
95 | |
96 // Get the default match for the query (not necessarily the first). Returns | |
97 // end() if there is no default match. | |
98 const_iterator default_match() const { return default_match_; } | |
99 | |
100 // Returns true if the top match is a verbatim search or URL match (see | |
101 // IsVerbatimType() in autocomplete_match.h), and the next match is not also | |
102 // some kind of verbatim match. In this case, the top match will be hidden, | |
103 // and nothing in the dropdown will appear selected by default; hitting enter | |
104 // will navigate to the (hidden) default match, while pressing the down arrow | |
105 // key will select the first visible match, which is actually the second match | |
106 // in the result set. | |
107 // | |
108 // Hiding the top match in these cases is possible because users should | |
109 // already know what will happen on hitting enter from the omnibox text | |
110 // itself, without needing to see the same text appear again, selected, just | |
111 // below their typing. Instead, by hiding the verbatim match, there is one | |
112 // less line to skip over in order to visually scan downwards to see other | |
113 // suggested matches. This makes it more likely that users will see and | |
114 // select useful non-verbatim matches. (Note that hiding the verbatim match | |
115 // this way is similar to how most other browsers' address bars behave.) | |
116 // | |
117 // We avoid hiding when the top two matches are both verbatim in order to | |
118 // avoid potential confusion if a user were to see the second match just below | |
119 // their typing and assume it would be the default action. | |
120 // | |
121 // Note that if the top match should be hidden and it is the only match, | |
122 // the dropdown should be closed. | |
123 bool ShouldHideTopMatch() const; | |
124 | |
125 // Returns true if the top match is a verbatim search or URL match (see | |
126 // IsVerbatimType() in autocomplete_match.h), and the next match is not also | |
127 // some kind of verbatim match. | |
128 bool TopMatchIsStandaloneVerbatimMatch() const; | |
129 | |
130 const GURL& alternate_nav_url() const { return alternate_nav_url_; } | |
131 | |
132 // Clears the matches for this result set. | |
133 void Reset(); | |
134 | |
135 void Swap(AutocompleteResult* other); | |
136 | |
137 #ifndef NDEBUG | |
138 // Does a data integrity check on this result. | |
139 void Validate() const; | |
140 #endif | |
141 | |
142 // Compute the "alternate navigation URL" for a given match. This is obtained | |
143 // by interpreting the user input directly as a URL. See comments on | |
144 // |alternate_nav_url_|. | |
145 static GURL ComputeAlternateNavUrl(const AutocompleteInput& input, | |
146 const AutocompleteMatch& match); | |
147 | |
148 // Sort |matches| by destination, taking into account demotions based on | |
149 // |page_classification| when resolving ties about which of several | |
150 // duplicates to keep. The matches are also deduplicated. If | |
151 // |set_duplicate_matches| is true, the duplicate matches are stored in the | |
152 // |duplicate_matches| vector of the corresponding AutocompleteMatch. | |
153 static void DedupMatchesByDestination( | |
154 metrics::OmniboxEventProto::PageClassification page_classification, | |
155 bool set_duplicate_matches, | |
156 ACMatches* matches); | |
157 | |
158 private: | |
159 friend class AutocompleteProviderTest; | |
160 | |
161 typedef std::map<AutocompleteProvider*, ACMatches> ProviderToMatches; | |
162 | |
163 #if defined(OS_ANDROID) | |
164 // iterator::difference_type is not defined in the STL that we compile with on | |
165 // Android. | |
166 typedef int matches_difference_type; | |
167 #else | |
168 typedef ACMatches::iterator::difference_type matches_difference_type; | |
169 #endif | |
170 | |
171 // Returns true if |matches| contains a match with the same destination as | |
172 // |match|. | |
173 static bool HasMatchByDestination(const AutocompleteMatch& match, | |
174 const ACMatches& matches); | |
175 | |
176 // operator=() by another name. | |
177 void CopyFrom(const AutocompleteResult& rhs); | |
178 | |
179 // Populates |provider_to_matches| from |matches_|. | |
180 void BuildProviderToMatches(ProviderToMatches* provider_to_matches) const; | |
181 | |
182 // Copies matches into this result. |old_matches| gives the matches from the | |
183 // last result, and |new_matches| the results from this result. | |
184 void MergeMatchesByProvider( | |
185 metrics::OmniboxEventProto::PageClassification page_classification, | |
186 const ACMatches& old_matches, | |
187 const ACMatches& new_matches); | |
188 | |
189 ACMatches matches_; | |
190 | |
191 const_iterator default_match_; | |
192 | |
193 // The "alternate navigation URL", if any, for this result set. This is a URL | |
194 // to try offering as a navigational option in case the user navigated to the | |
195 // URL of the default match but intended something else. For example, if the | |
196 // user's local intranet contains site "foo", and the user types "foo", we | |
197 // default to searching for "foo" when the user may have meant to navigate | |
198 // there. In cases like this, the default match will point to the "search for | |
199 // 'foo'" result, and this will contain "http://foo/". | |
200 GURL alternate_nav_url_; | |
201 | |
202 DISALLOW_COPY_AND_ASSIGN(AutocompleteResult); | |
203 }; | |
204 | |
205 #endif // CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_RESULT_H_ | |
OLD | NEW |