OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ui/omnibox/omnibox_controller.h" | 5 #include "chrome/browser/ui/omnibox/omnibox_controller.h" |
6 | 6 |
7 #include "base/metrics/histogram.h" | 7 #include "base/metrics/histogram.h" |
8 #include "chrome/browser/autocomplete/autocomplete_classifier.h" | 8 #include "chrome/browser/autocomplete/autocomplete_classifier.h" |
9 #include "chrome/browser/autocomplete/autocomplete_match.h" | 9 #include "chrome/browser/autocomplete/autocomplete_match.h" |
10 #include "chrome/browser/autocomplete/search_provider.h" | 10 #include "chrome/browser/autocomplete/search_provider.h" |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
43 string16 user_text, | 43 string16 user_text, |
44 size_t cursor_position, | 44 size_t cursor_position, |
45 const GURL& current_url, | 45 const GURL& current_url, |
46 bool prevent_inline_autocomplete, | 46 bool prevent_inline_autocomplete, |
47 bool prefer_keyword, | 47 bool prefer_keyword, |
48 bool allow_exact_keyword_match, | 48 bool allow_exact_keyword_match, |
49 int omnibox_start_margin) const { | 49 int omnibox_start_margin) const { |
50 ClearPopupKeywordMode(); | 50 ClearPopupKeywordMode(); |
51 popup_->SetHoveredLine(OmniboxPopupModel::kNoMatch); | 51 popup_->SetHoveredLine(OmniboxPopupModel::kNoMatch); |
52 | 52 |
53 #if defined(HTML_INSTANT_EXTENDED_POPUP) | |
54 InstantController* instant_controller = GetInstantController(); | |
55 if (instant_controller) | |
56 instant_controller->OnAutocompleteStart(); | |
57 #endif | |
58 if (chrome::IsInstantExtendedAPIEnabled()) { | 53 if (chrome::IsInstantExtendedAPIEnabled()) { |
59 autocomplete_controller_->search_provider()-> | 54 autocomplete_controller_->search_provider()-> |
60 SetOmniboxStartMargin(omnibox_start_margin); | 55 SetOmniboxStartMargin(omnibox_start_margin); |
61 } | 56 } |
62 | 57 |
63 // We don't explicitly clear OmniboxPopupModel::manually_selected_match, as | 58 // We don't explicitly clear OmniboxPopupModel::manually_selected_match, as |
64 // Start ends up invoking OmniboxPopupModel::OnResultChanged which clears it. | 59 // Start ends up invoking OmniboxPopupModel::OnResultChanged which clears it. |
65 autocomplete_controller_->Start(AutocompleteInput( | 60 autocomplete_controller_->Start(AutocompleteInput( |
66 user_text, cursor_position, string16(), current_url, | 61 user_text, cursor_position, string16(), current_url, |
67 prevent_inline_autocomplete, prefer_keyword, allow_exact_keyword_match, | 62 prevent_inline_autocomplete, prefer_keyword, allow_exact_keyword_match, |
(...skipping 21 matching lines...) Expand all Loading... |
89 current_match_.inline_autocomplete_offset = | 84 current_match_.inline_autocomplete_offset = |
90 current_match_.fill_into_edit.length(); | 85 current_match_.fill_into_edit.length(); |
91 current_match_.fill_into_edit += match->fill_into_edit.substr( | 86 current_match_.fill_into_edit += match->fill_into_edit.substr( |
92 match->inline_autocomplete_offset); | 87 match->inline_autocomplete_offset); |
93 } else { | 88 } else { |
94 current_match_.inline_autocomplete_offset = string16::npos; | 89 current_match_.inline_autocomplete_offset = string16::npos; |
95 } | 90 } |
96 | 91 |
97 if (!prerender::IsOmniboxEnabled(profile_)) | 92 if (!prerender::IsOmniboxEnabled(profile_)) |
98 DoPreconnect(*match); | 93 DoPreconnect(*match); |
99 omnibox_edit_model_->OnCurrentMatchChanged(false); | 94 omnibox_edit_model_->OnCurrentMatchChanged(); |
100 } else { | 95 } else { |
101 InvalidateCurrentMatch(); | 96 InvalidateCurrentMatch(); |
102 popup_->OnResultChanged(); | 97 popup_->OnResultChanged(); |
103 omnibox_edit_model_->OnPopupDataChanged(string16(), NULL, string16(), | 98 omnibox_edit_model_->OnPopupDataChanged(string16(), NULL, string16(), |
104 false); | 99 false); |
105 } | 100 } |
106 } else { | 101 } else { |
107 popup_->OnResultChanged(); | 102 popup_->OnResultChanged(); |
108 } | 103 } |
109 | 104 |
110 // TODO(beaudoin): This may no longer be needed now that instant classic is | 105 if (!popup_->IsOpen() && was_open) { |
111 // gone. | |
112 if (popup_->IsOpen()) { | |
113 // The popup size may have changed, let instant know. | |
114 OnPopupBoundsChanged(popup_->view()->GetTargetBounds()); | |
115 | |
116 #if defined(HTML_INSTANT_EXTENDED_POPUP) | |
117 InstantController* instant_controller = GetInstantController(); | |
118 if (instant_controller && !omnibox_edit_model_->in_revert()) { | |
119 instant_controller->HandleAutocompleteResults( | |
120 *autocomplete_controller_->providers(), | |
121 autocomplete_controller_->result()); | |
122 } | |
123 #endif | |
124 } else if (was_open) { | |
125 // Accept the temporary text as the user text, because it makes little sense | 106 // Accept the temporary text as the user text, because it makes little sense |
126 // to have temporary text when the popup is closed. | 107 // to have temporary text when the popup is closed. |
127 omnibox_edit_model_->AcceptTemporaryTextAsUserText(); | 108 omnibox_edit_model_->AcceptTemporaryTextAsUserText(); |
128 // The popup has been closed, let instant know. | |
129 OnPopupBoundsChanged(gfx::Rect()); | |
130 } | 109 } |
131 } | 110 } |
132 | 111 |
133 bool OmniboxController::DoInstant(const AutocompleteMatch& match, | |
134 string16 user_text, | |
135 string16 full_text, | |
136 size_t selection_start, | |
137 size_t selection_end, | |
138 bool user_input_in_progress, | |
139 bool in_escape_handler, | |
140 bool just_deleted_text, | |
141 bool keyword_is_selected) { | |
142 #if defined(HTML_INSTANT_EXTENDED_POPUP) | |
143 InstantController* instant_controller = GetInstantController(); | |
144 if (!instant_controller) | |
145 return false; | |
146 | |
147 // Remove "?" if we're in forced query mode. | |
148 AutocompleteInput::RemoveForcedQueryStringIfNecessary( | |
149 autocomplete_controller_->input().type(), &user_text); | |
150 AutocompleteInput::RemoveForcedQueryStringIfNecessary( | |
151 autocomplete_controller_->input().type(), &full_text); | |
152 return instant_controller->Update( | |
153 match, user_text, full_text, selection_start, selection_end, | |
154 UseVerbatimInstant(just_deleted_text), user_input_in_progress, | |
155 popup_->IsOpen(), in_escape_handler, keyword_is_selected); | |
156 #else | |
157 return false; | |
158 #endif | |
159 } | |
160 | |
161 void OmniboxController::SetInstantSuggestion( | 112 void OmniboxController::SetInstantSuggestion( |
162 const InstantSuggestion& suggestion) { | 113 const InstantSuggestion& suggestion) { |
163 // Should only get called for the HTML popup. | 114 // TODO(jered): Delete this. |
164 #if defined(HTML_INSTANT_EXTENDED_POPUP) | |
165 switch (suggestion.behavior) { | |
166 case INSTANT_COMPLETE_NOW: | |
167 // Set blue suggestion text. | |
168 // TODO(beaudoin): Create a valid current_match_ and call | |
169 // omnibox_edit_model_->OnCurrentMatchChanged. | |
170 return; | |
171 | |
172 case INSTANT_COMPLETE_NEVER: { | |
173 DCHECK_EQ(INSTANT_SUGGESTION_SEARCH, suggestion.type); | |
174 | |
175 // Set gray suggestion text. | |
176 // Remove "?" if we're in forced query mode. | |
177 gray_suggestion_ = suggestion.text; | |
178 | |
179 omnibox_edit_model_->OnGrayTextChanged(); | |
180 return; | |
181 } | |
182 | |
183 case INSTANT_COMPLETE_REPLACE: | |
184 // Replace the entire omnibox text by the suggestion the user just arrowed | |
185 // to. | |
186 CreateAndSetInstantMatch(suggestion.text, suggestion.text, | |
187 suggestion.type == INSTANT_SUGGESTION_SEARCH ? | |
188 AutocompleteMatchType::SEARCH_SUGGEST : | |
189 AutocompleteMatchType::URL_WHAT_YOU_TYPED); | |
190 | |
191 omnibox_edit_model_->OnCurrentMatchChanged(true); | |
192 return; | |
193 } | |
194 #endif | |
195 } | 115 } |
196 | 116 |
197 void OmniboxController::InvalidateCurrentMatch() { | 117 void OmniboxController::InvalidateCurrentMatch() { |
198 current_match_ = AutocompleteMatch(); | 118 current_match_ = AutocompleteMatch(); |
199 } | 119 } |
200 | 120 |
201 void OmniboxController::ClearPopupKeywordMode() const { | 121 void OmniboxController::ClearPopupKeywordMode() const { |
202 if (popup_->IsOpen() && | 122 if (popup_->IsOpen() && |
203 popup_->selected_line_state() == OmniboxPopupModel::KEYWORD) | 123 popup_->selected_line_state() == OmniboxPopupModel::KEYWORD) |
204 popup_->SetSelectedLineState(OmniboxPopupModel::NORMAL); | 124 popup_->SetSelectedLineState(OmniboxPopupModel::NORMAL); |
205 } | 125 } |
206 | 126 |
207 void OmniboxController::DoPreconnect(const AutocompleteMatch& match) { | 127 void OmniboxController::DoPreconnect(const AutocompleteMatch& match) { |
208 if (!match.destination_url.SchemeIs(extensions::kExtensionScheme)) { | 128 if (!match.destination_url.SchemeIs(extensions::kExtensionScheme)) { |
209 // Warm up DNS Prefetch cache, or preconnect to a search service. | 129 // Warm up DNS Prefetch cache, or preconnect to a search service. |
210 UMA_HISTOGRAM_ENUMERATION("Autocomplete.MatchType", match.type, | 130 UMA_HISTOGRAM_ENUMERATION("Autocomplete.MatchType", match.type, |
211 AutocompleteMatchType::NUM_TYPES); | 131 AutocompleteMatchType::NUM_TYPES); |
212 if (profile_->GetNetworkPredictor()) { | 132 if (profile_->GetNetworkPredictor()) { |
213 profile_->GetNetworkPredictor()->AnticipateOmniboxUrl( | 133 profile_->GetNetworkPredictor()->AnticipateOmniboxUrl( |
214 match.destination_url, | 134 match.destination_url, |
215 predictors::AutocompleteActionPredictor::IsPreconnectable(match)); | 135 predictors::AutocompleteActionPredictor::IsPreconnectable(match)); |
216 } | 136 } |
217 // We could prefetch the alternate nav URL, if any, but because there | 137 // We could prefetch the alternate nav URL, if any, but because there |
218 // can be many of these as a user types an initial series of characters, | 138 // can be many of these as a user types an initial series of characters, |
219 // the OS DNS cache could suffer eviction problems for minimal gain. | 139 // the OS DNS cache could suffer eviction problems for minimal gain. |
220 } | 140 } |
221 } | 141 } |
222 | 142 |
223 void OmniboxController::OnPopupBoundsChanged(const gfx::Rect& bounds) { | |
224 InstantController* instant_controller = GetInstantController(); | |
225 if (instant_controller) | |
226 instant_controller->SetPopupBounds(bounds); | |
227 } | |
228 | |
229 bool OmniboxController::UseVerbatimInstant(bool just_deleted_text) const { | 143 bool OmniboxController::UseVerbatimInstant(bool just_deleted_text) const { |
230 #if defined(OS_MACOSX) | 144 #if defined(OS_MACOSX) |
231 // TODO(suzhe): Fix Mac port to display Instant suggest in a separated NSView, | 145 // TODO(suzhe): Fix Mac port to display Instant suggest in a separated NSView, |
232 // so that we can display Instant suggest along with composition text. | 146 // so that we can display Instant suggest along with composition text. |
233 const AutocompleteInput& input = autocomplete_controller_->input(); | 147 const AutocompleteInput& input = autocomplete_controller_->input(); |
234 if (input.prevent_inline_autocomplete()) | 148 if (input.prevent_inline_autocomplete()) |
235 return true; | 149 return true; |
236 #endif | 150 #endif |
237 | 151 |
238 // The value of input.prevent_inline_autocomplete() is determined by the | 152 // The value of input.prevent_inline_autocomplete() is determined by the |
(...skipping 22 matching lines...) Expand all Loading... |
261 | 175 |
262 TemplateURL* template_url = | 176 TemplateURL* template_url = |
263 template_url_service->GetDefaultSearchProvider(); | 177 template_url_service->GetDefaultSearchProvider(); |
264 if (!template_url) | 178 if (!template_url) |
265 return; | 179 return; |
266 | 180 |
267 current_match_ = SearchProvider::CreateSearchSuggestion( | 181 current_match_ = SearchProvider::CreateSearchSuggestion( |
268 NULL, 0, match_type, template_url, query_string, input_text, | 182 NULL, 0, match_type, template_url, query_string, input_text, |
269 AutocompleteInput(), false, 0, -1, true); | 183 AutocompleteInput(), false, 0, -1, true); |
270 } | 184 } |
OLD | NEW |