OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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_edit_model.h" | 5 #include "chrome/browser/ui/omnibox/omnibox_edit_model.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/format_macros.h" | 9 #include "base/format_macros.h" |
10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
90 controller_(controller), | 90 controller_(controller), |
91 has_focus_(false), | 91 has_focus_(false), |
92 user_input_in_progress_(false), | 92 user_input_in_progress_(false), |
93 just_deleted_text_(false), | 93 just_deleted_text_(false), |
94 has_temporary_text_(false), | 94 has_temporary_text_(false), |
95 paste_state_(NONE), | 95 paste_state_(NONE), |
96 control_key_state_(UP), | 96 control_key_state_(UP), |
97 is_keyword_hint_(false), | 97 is_keyword_hint_(false), |
98 profile_(profile), | 98 profile_(profile), |
99 in_revert_(false), | 99 in_revert_(false), |
100 allow_exact_keyword_match_(false), | 100 allow_exact_keyword_match_(false) { |
101 instant_complete_behavior_(INSTANT_COMPLETE_DELAYED) { | |
102 } | 101 } |
103 | 102 |
104 OmniboxEditModel::~OmniboxEditModel() { | 103 OmniboxEditModel::~OmniboxEditModel() { |
105 } | 104 } |
106 | 105 |
107 const OmniboxEditModel::State OmniboxEditModel::GetStateForTabSwitch() { | 106 const OmniboxEditModel::State OmniboxEditModel::GetStateForTabSwitch() { |
108 // Like typing, switching tabs "accepts" the temporary text as the user | 107 // Like typing, switching tabs "accepts" the temporary text as the user |
109 // text, because it makes little sense to have temporary text when the | 108 // text, because it makes little sense to have temporary text when the |
110 // popup is closed. | 109 // popup is closed. |
111 if (user_input_in_progress_) { | 110 if (user_input_in_progress_) { |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
179 SearchProvider* search_provider = | 178 SearchProvider* search_provider = |
180 autocomplete_controller_->search_provider(); | 179 autocomplete_controller_->search_provider(); |
181 // There may be no providers during testing; guard against that. | 180 // There may be no providers during testing; guard against that. |
182 if (search_provider) | 181 if (search_provider) |
183 search_provider->FinalizeInstantQuery(input_text, suggest_text); | 182 search_provider->FinalizeInstantQuery(input_text, suggest_text); |
184 } | 183 } |
185 } | 184 } |
186 | 185 |
187 void OmniboxEditModel::SetSuggestedText(const string16& text, | 186 void OmniboxEditModel::SetSuggestedText(const string16& text, |
188 InstantCompleteBehavior behavior) { | 187 InstantCompleteBehavior behavior) { |
189 instant_complete_behavior_ = behavior; | 188 if (behavior == INSTANT_COMPLETE_NOW) { |
190 if (instant_complete_behavior_ == INSTANT_COMPLETE_NOW) { | |
191 if (!text.empty()) | 189 if (!text.empty()) |
192 FinalizeInstantQuery(view_->GetText(), text, false); | 190 FinalizeInstantQuery(view_->GetText(), text, false); |
193 else | 191 else |
194 view_->SetInstantSuggestion(text, false); | 192 view_->SetInstantSuggestion(text, false); |
195 } else { | 193 } else { |
196 DCHECK((behavior == INSTANT_COMPLETE_DELAYED) || | 194 DCHECK((behavior == INSTANT_COMPLETE_DELAYED) || |
197 (behavior == INSTANT_COMPLETE_NEVER)); | 195 (behavior == INSTANT_COMPLETE_NEVER)); |
198 view_->SetInstantSuggestion(text, behavior == INSTANT_COMPLETE_DELAYED); | 196 view_->SetInstantSuggestion(text, behavior == INSTANT_COMPLETE_DELAYED); |
199 } | 197 } |
200 } | 198 } |
201 | 199 |
202 bool OmniboxEditModel::CommitSuggestedText(bool skip_inline_autocomplete) { | 200 bool OmniboxEditModel::CommitSuggestedText(bool skip_inline_autocomplete) { |
203 if (!controller_->GetInstant()) | 201 if (!controller_->GetInstant()) |
204 return false; | 202 return false; |
205 | 203 |
206 const string16 suggestion = view_->GetInstantSuggestion(); | 204 const string16 suggestion = view_->GetInstantSuggestion(); |
207 if (suggestion.empty()) | 205 if (suggestion.empty()) |
208 return false; | 206 return false; |
209 | 207 |
210 FinalizeInstantQuery(view_->GetText(), suggestion, skip_inline_autocomplete); | 208 FinalizeInstantQuery(view_->GetText(), suggestion, skip_inline_autocomplete); |
211 return true; | 209 return true; |
212 } | 210 } |
213 | 211 |
214 bool OmniboxEditModel::AcceptCurrentInstantPreview() { | 212 bool OmniboxEditModel::AcceptCurrentInstantPreview() { |
215 InstantController* instant = controller_->GetInstant(); | 213 InstantController* instant = controller_->GetInstant(); |
216 return instant && instant->CommitIfCurrent(); | 214 return instant && instant->IsCurrent() && |
215 instant->CommitCurrentPreview(INSTANT_COMMIT_PRESSED_ENTER); | |
217 } | 216 } |
218 | 217 |
219 void OmniboxEditModel::OnChanged() { | 218 void OmniboxEditModel::OnChanged() { |
220 // Don't call CurrentMatch() when there's no editing, as in this case we'll | 219 // Don't call CurrentMatch() when there's no editing, as in this case we'll |
221 // never actually use it. This avoids running the autocomplete providers (and | 220 // never actually use it. This avoids running the autocomplete providers (and |
222 // any systems they then spin up) during startup. | 221 // any systems they then spin up) during startup. |
223 const AutocompleteMatch& current_match = user_input_in_progress_ ? | 222 const AutocompleteMatch& current_match = user_input_in_progress_ ? |
224 CurrentMatch() : AutocompleteMatch(); | 223 CurrentMatch() : AutocompleteMatch(); |
225 | 224 |
226 AutocompleteActionPredictor::Action recommended_action = | 225 AutocompleteActionPredictor::Action recommended_action = |
227 AutocompleteActionPredictor::ACTION_NONE; | 226 AutocompleteActionPredictor::ACTION_NONE; |
228 AutocompleteActionPredictor* action_predictor = | 227 AutocompleteActionPredictor* action_predictor = |
229 user_input_in_progress_ ? | 228 user_input_in_progress_ ? |
230 AutocompleteActionPredictorFactory::GetForProfile(profile_) : NULL; | 229 AutocompleteActionPredictorFactory::GetForProfile(profile_) : NULL; |
231 if (action_predictor) { | 230 if (action_predictor) { |
232 action_predictor->RegisterTransitionalMatches(user_text_, result()); | 231 action_predictor->RegisterTransitionalMatches(user_text_, result()); |
233 // Confer with the AutocompleteActionPredictor to determine what action, if | 232 // Confer with the AutocompleteActionPredictor to determine what action, if |
234 // any, we should take. Get the recommended action here even if we don't | 233 // any, we should take. Get the recommended action here even if we don't |
235 // need it so we can get stats for anyone who is opted in to UMA, but only | 234 // need it so we can get stats for anyone who is opted in to UMA, but only |
236 // get it if the user has actually typed something to avoid constructing it | 235 // get it if the user has actually typed something to avoid constructing it |
237 // before it's needed. Note: This event is triggered as part of startup when | 236 // before it's needed. Note: This event is triggered as part of startup when |
238 // the initial tab transitions to the start page. | 237 // the initial tab transitions to the start page. |
239 recommended_action = | 238 recommended_action = |
240 action_predictor->RecommendAction(user_text_, current_match); | 239 action_predictor->RecommendAction(user_text_, current_match); |
241 } | 240 } |
242 | 241 |
243 UMA_HISTOGRAM_ENUMERATION("AutocompleteActionPredictor.Action", | 242 UMA_HISTOGRAM_ENUMERATION("AutocompleteActionPredictor.Action", |
244 recommended_action, | 243 recommended_action, |
245 AutocompleteActionPredictor::LAST_PREDICT_ACTION); | 244 AutocompleteActionPredictor::LAST_PREDICT_ACTION); |
245 | |
246 string16 suggested_text; | 246 string16 suggested_text; |
247 InstantCompleteBehavior complete_behavior = INSTANT_COMPLETE_NOW; | |
247 | 248 |
248 if (DoInstant(current_match, &suggested_text)) { | 249 if (DoInstant(current_match, &suggested_text, &complete_behavior)) { |
249 SetSuggestedText(suggested_text, instant_complete_behavior_); | 250 SetSuggestedText(suggested_text, complete_behavior); |
250 } else { | 251 } else { |
251 switch (recommended_action) { | 252 switch (recommended_action) { |
252 case AutocompleteActionPredictor::ACTION_PRERENDER: | 253 case AutocompleteActionPredictor::ACTION_PRERENDER: |
253 DoPrerender(current_match); | 254 DoPrerender(current_match); |
254 break; | 255 break; |
255 case AutocompleteActionPredictor::ACTION_PRECONNECT: | 256 case AutocompleteActionPredictor::ACTION_PRECONNECT: |
256 DoPreconnect(current_match); | 257 DoPreconnect(current_match); |
257 break; | 258 break; |
258 case AutocompleteActionPredictor::ACTION_NONE: | 259 case AutocompleteActionPredictor::ACTION_NONE: |
259 break; | 260 break; |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
435 (has_selected_text && inline_autocomplete_text_.empty()) || | 436 (has_selected_text && inline_autocomplete_text_.empty()) || |
436 (paste_state_ != NONE), keyword_is_selected, | 437 (paste_state_ != NONE), keyword_is_selected, |
437 keyword_is_selected || allow_exact_keyword_match_, | 438 keyword_is_selected || allow_exact_keyword_match_, |
438 AutocompleteInput::ALL_MATCHES); | 439 AutocompleteInput::ALL_MATCHES); |
439 } | 440 } |
440 | 441 |
441 void OmniboxEditModel::StopAutocomplete() { | 442 void OmniboxEditModel::StopAutocomplete() { |
442 if (popup_->IsOpen() && !in_revert_) { | 443 if (popup_->IsOpen() && !in_revert_) { |
443 InstantController* instant = controller_->GetInstant(); | 444 InstantController* instant = controller_->GetInstant(); |
444 if (instant && !instant->commit_on_pointer_release()) | 445 if (instant && !instant->commit_on_pointer_release()) |
445 instant->DestroyPreviewContents(); | 446 instant->Hide(); |
446 } | 447 } |
447 | 448 |
448 autocomplete_controller_->Stop(true); | 449 autocomplete_controller_->Stop(true); |
449 } | 450 } |
450 | 451 |
451 bool OmniboxEditModel::CanPasteAndGo(const string16& text) const { | 452 bool OmniboxEditModel::CanPasteAndGo(const string16& text) const { |
452 if (!view_->GetCommandUpdater()->IsCommandEnabled(IDC_OPEN_CURRENT_URL)) | 453 if (!view_->GetCommandUpdater()->IsCommandEnabled(IDC_OPEN_CURRENT_URL)) |
453 return false; | 454 return false; |
454 | 455 |
455 AutocompleteMatch match; | 456 AutocompleteMatch match; |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
623 } | 624 } |
624 controller_->OnAutocompleteAccept(destination_url, disposition, | 625 controller_->OnAutocompleteAccept(destination_url, disposition, |
625 match.transition, alternate_nav_url); | 626 match.transition, alternate_nav_url); |
626 } | 627 } |
627 | 628 |
628 if (match.starred) | 629 if (match.starred) |
629 bookmark_utils::RecordBookmarkLaunch(bookmark_utils::LAUNCH_OMNIBOX); | 630 bookmark_utils::RecordBookmarkLaunch(bookmark_utils::LAUNCH_OMNIBOX); |
630 | 631 |
631 InstantController* instant = controller_->GetInstant(); | 632 InstantController* instant = controller_->GetInstant(); |
632 if (instant && !popup_->IsOpen()) | 633 if (instant && !popup_->IsOpen()) |
633 instant->DestroyPreviewContents(); | 634 instant->Hide(); |
634 in_revert_ = false; | 635 in_revert_ = false; |
635 } | 636 } |
636 | 637 |
637 bool OmniboxEditModel::AcceptKeyword() { | 638 bool OmniboxEditModel::AcceptKeyword() { |
638 DCHECK(is_keyword_hint_ && !keyword_.empty()); | 639 DCHECK(is_keyword_hint_ && !keyword_.empty()); |
639 | 640 |
640 autocomplete_controller_->Stop(false); | 641 autocomplete_controller_->Stop(false); |
641 is_keyword_hint_ = false; | 642 is_keyword_hint_ = false; |
642 | 643 |
643 if (popup_->IsOpen()) | 644 if (popup_->IsOpen()) |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
693 InstantController* instant = controller_->GetInstant(); | 694 InstantController* instant = controller_->GetInstant(); |
694 if (instant) | 695 if (instant) |
695 instant->OnAutocompleteGotFocus(); | 696 instant->OnAutocompleteGotFocus(); |
696 | 697 |
697 NotifySearchTabHelper(); | 698 NotifySearchTabHelper(); |
698 } | 699 } |
699 | 700 |
700 void OmniboxEditModel::OnWillKillFocus(gfx::NativeView view_gaining_focus) { | 701 void OmniboxEditModel::OnWillKillFocus(gfx::NativeView view_gaining_focus) { |
701 SetSuggestedText(string16(), INSTANT_COMPLETE_NOW); | 702 SetSuggestedText(string16(), INSTANT_COMPLETE_NOW); |
702 | 703 |
703 InstantController* instant = controller_->GetInstant(); | 704 if (InstantController* instant = controller_->GetInstant()) |
704 if (instant) | |
705 instant->OnAutocompleteLostFocus(view_gaining_focus); | 705 instant->OnAutocompleteLostFocus(view_gaining_focus); |
706 | 706 |
707 NotifySearchTabHelper(); | 707 NotifySearchTabHelper(); |
708 } | 708 } |
709 | 709 |
710 void OmniboxEditModel::OnKillFocus() { | 710 void OmniboxEditModel::OnKillFocus() { |
711 has_focus_ = false; | 711 has_focus_ = false; |
712 control_key_state_ = UP; | 712 control_key_state_ = UP; |
713 paste_state_ = NONE; | 713 paste_state_ = NONE; |
714 } | 714 } |
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1097 GetKeywordForText(keyword).empty(); | 1097 GetKeywordForText(keyword).empty(); |
1098 } | 1098 } |
1099 | 1099 |
1100 void OmniboxEditModel::NotifySearchTabHelper() { | 1100 void OmniboxEditModel::NotifySearchTabHelper() { |
1101 if (controller_->GetTabContents()) { | 1101 if (controller_->GetTabContents()) { |
1102 controller_->GetTabContents()->search_tab_helper()-> | 1102 controller_->GetTabContents()->search_tab_helper()-> |
1103 OmniboxEditModelChanged(this); | 1103 OmniboxEditModelChanged(this); |
1104 } | 1104 } |
1105 } | 1105 } |
1106 | 1106 |
1107 bool OmniboxEditModel::DoInstant(const AutocompleteMatch& match, | 1107 bool OmniboxEditModel::DoInstant( |
1108 string16* suggested_text) { | 1108 const AutocompleteMatch& match, |
1109 string16* suggested_text, | |
1110 InstantCompleteBehavior* complete_behavior) { | |
1109 DCHECK(suggested_text); | 1111 DCHECK(suggested_text); |
1112 DCHECK(complete_behavior); | |
1110 | 1113 |
1111 if (in_revert_) | 1114 if (in_revert_) |
1112 return false; | 1115 return false; |
1113 | 1116 |
1114 InstantController* instant = controller_->GetInstant(); | 1117 InstantController* instant = controller_->GetInstant(); |
1115 | 1118 |
1116 if (!instant) | 1119 if (!instant) |
1117 return false; | 1120 return false; |
1118 | 1121 |
1119 if (user_input_in_progress_ && popup_->IsOpen()) { | 1122 if (user_input_in_progress_ && popup_->IsOpen()) { |
1120 return instant->Update(match, view_->GetText(), UseVerbatimInstant(), | 1123 string16 text = view_->GetText(); |
1121 suggested_text); | 1124 AutocompleteInput::RemoveForcedQueryStringIfNecessary( |
1125 autocomplete_controller_->input().type(), &text); | |
sky
2012/08/07 15:57:21
nit: indent 2 more
sreeram
2012/08/07 16:35:03
Done.
| |
1126 | |
1127 // If there's any inline autocompletion, split it out from |text|. | |
1128 if (!inline_autocomplete_text_.empty()) { | |
1129 DCHECK_GE(text.size(), inline_autocomplete_text_.size()); | |
1130 text.resize(text.size() - inline_autocomplete_text_.size()); | |
1131 *suggested_text = inline_autocomplete_text_; | |
1132 } | |
1133 | |
1134 return instant->Update(match, text, UseVerbatimInstant(), suggested_text, | |
1135 complete_behavior); | |
1122 } | 1136 } |
1123 | 1137 |
1124 // It's possible DoInstant() was called due to an OnChanged() event from the | 1138 // It's possible DoInstant() was called due to an OnChanged() event from the |
1125 // omnibox view if the user clicked the renderer while IME composition was | 1139 // omnibox view if the user clicked the renderer while IME composition was |
1126 // active. In that case we still want to commit on mouse up, so don't call | 1140 // active. In that case we still want to commit on mouse up, so don't call |
1127 // Hide(). | 1141 // Hide(). |
1128 if (!instant->commit_on_pointer_release()) | 1142 if (!instant->commit_on_pointer_release()) |
1129 instant->Hide(); | 1143 instant->Hide(); |
1130 return false; | 1144 return false; |
1131 } | 1145 } |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1191 } | 1205 } |
1192 | 1206 |
1193 void OmniboxEditModel::ClassifyStringForPasteAndGo( | 1207 void OmniboxEditModel::ClassifyStringForPasteAndGo( |
1194 const string16& text, | 1208 const string16& text, |
1195 AutocompleteMatch* match, | 1209 AutocompleteMatch* match, |
1196 GURL* alternate_nav_url) const { | 1210 GURL* alternate_nav_url) const { |
1197 DCHECK(match); | 1211 DCHECK(match); |
1198 AutocompleteClassifierFactory::GetForProfile(profile_)->Classify(text, | 1212 AutocompleteClassifierFactory::GetForProfile(profile_)->Classify(text, |
1199 string16(), false, false, match, alternate_nav_url); | 1213 string16(), false, false, match, alternate_nav_url); |
1200 } | 1214 } |
OLD | NEW |