Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(316)

Side by Side Diff: chrome/browser/ui/omnibox/omnibox_edit_model.cc

Issue 11413217: Instant API: tell page whether the browser is capturing key strokes. (Closed) Base URL: http://git.chromium.org/chromium/src.git@focus
Patch Set: Rebase. Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 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 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 using predictors::AutocompleteActionPredictor; 64 using predictors::AutocompleteActionPredictor;
65 using predictors::AutocompleteActionPredictorFactory; 65 using predictors::AutocompleteActionPredictorFactory;
66 66
67 /////////////////////////////////////////////////////////////////////////////// 67 ///////////////////////////////////////////////////////////////////////////////
68 // OmniboxEditModel::State 68 // OmniboxEditModel::State
69 69
70 OmniboxEditModel::State::State(bool user_input_in_progress, 70 OmniboxEditModel::State::State(bool user_input_in_progress,
71 const string16& user_text, 71 const string16& user_text,
72 const string16& keyword, 72 const string16& keyword,
73 bool is_keyword_hint, 73 bool is_keyword_hint,
74 bool is_caret_visible) 74 OmniboxFocusState focus_state)
75 : user_input_in_progress(user_input_in_progress), 75 : user_input_in_progress(user_input_in_progress),
76 user_text(user_text), 76 user_text(user_text),
77 keyword(keyword), 77 keyword(keyword),
78 is_keyword_hint(is_keyword_hint), 78 is_keyword_hint(is_keyword_hint),
79 is_caret_visible(is_caret_visible) { 79 focus_state(focus_state) {
80 } 80 }
81 81
82 OmniboxEditModel::State::~State() { 82 OmniboxEditModel::State::~State() {
83 } 83 }
84 84
85 /////////////////////////////////////////////////////////////////////////////// 85 ///////////////////////////////////////////////////////////////////////////////
86 // OmniboxEditModel 86 // OmniboxEditModel
87 87
88 OmniboxEditModel::OmniboxEditModel(OmniboxView* view, 88 OmniboxEditModel::OmniboxEditModel(OmniboxView* view,
89 OmniboxEditController* controller, 89 OmniboxEditController* controller,
90 Profile* profile) 90 Profile* profile)
91 : view_(view), 91 : view_(view),
92 popup_(NULL), 92 popup_(NULL),
93 controller_(controller), 93 controller_(controller),
94 has_focus_(false), 94 focus_state_(OMNIBOX_FOCUS_NONE),
95 is_caret_visible_(true),
96 user_input_in_progress_(false), 95 user_input_in_progress_(false),
97 just_deleted_text_(false), 96 just_deleted_text_(false),
98 has_temporary_text_(false), 97 has_temporary_text_(false),
99 is_temporary_text_set_by_instant_(false), 98 is_temporary_text_set_by_instant_(false),
100 paste_state_(NONE), 99 paste_state_(NONE),
101 control_key_state_(UP), 100 control_key_state_(UP),
102 is_keyword_hint_(false), 101 is_keyword_hint_(false),
103 profile_(profile), 102 profile_(profile),
104 in_revert_(false), 103 in_revert_(false),
105 allow_exact_keyword_match_(false) { 104 allow_exact_keyword_match_(false) {
(...skipping 19 matching lines...) Expand all
125 const string16 user_text(UserTextFromDisplayText(view_->GetText())); 124 const string16 user_text(UserTextFromDisplayText(view_->GetText()));
126 if (user_text.empty()) { 125 if (user_text.empty()) {
127 view_->RevertAll(); 126 view_->RevertAll();
128 view_->SelectAll(true); 127 view_->SelectAll(true);
129 } else { 128 } else {
130 InternalSetUserText(user_text); 129 InternalSetUserText(user_text);
131 } 130 }
132 } 131 }
133 132
134 return State(user_input_in_progress_, user_text_, keyword_, is_keyword_hint_, 133 return State(user_input_in_progress_, user_text_, keyword_, is_keyword_hint_,
135 is_caret_visible_); 134 focus_state_);
136 } 135 }
137 136
138 void OmniboxEditModel::RestoreState(const State& state) { 137 void OmniboxEditModel::RestoreState(const State& state) {
139 SetCaretVisibility(state.is_caret_visible); 138 SetFocusState(state.focus_state, OMNIBOX_FOCUS_CHANGE_TAB_SWITCH);
140 // Restore any user editing. 139 // Restore any user editing.
141 if (state.user_input_in_progress) { 140 if (state.user_input_in_progress) {
142 // NOTE: Be sure and set keyword-related state BEFORE invoking 141 // NOTE: Be sure and set keyword-related state BEFORE invoking
143 // DisplayTextFromUserText(), as its result depends upon this state. 142 // DisplayTextFromUserText(), as its result depends upon this state.
144 keyword_ = state.keyword; 143 keyword_ = state.keyword;
145 is_keyword_hint_ = state.is_keyword_hint; 144 is_keyword_hint_ = state.is_keyword_hint;
146 view_->SetUserText(state.user_text, 145 view_->SetUserText(state.user_text,
147 DisplayTextFromUserText(state.user_text), false); 146 DisplayTextFromUserText(state.user_text), false);
148 } 147 }
149 } 148 }
150 149
151 AutocompleteMatch OmniboxEditModel::CurrentMatch() { 150 AutocompleteMatch OmniboxEditModel::CurrentMatch() {
152 AutocompleteMatch match; 151 AutocompleteMatch match;
153 GetInfoForCurrentText(&match, NULL); 152 GetInfoForCurrentText(&match, NULL);
154 return match; 153 return match;
155 } 154 }
156 155
157 bool OmniboxEditModel::UpdatePermanentText(const string16& new_permanent_text) { 156 bool OmniboxEditModel::UpdatePermanentText(const string16& new_permanent_text) {
158 // When there's a new URL, and the user is not editing anything or the edit 157 // When there's a new URL, and the user is not editing anything or the edit
159 // doesn't have focus, we want to revert the edit to show the new URL. (The 158 // doesn't have focus, we want to revert the edit to show the new URL. (The
160 // common case where the edit doesn't have focus is when the user has started 159 // common case where the edit doesn't have focus is when the user has started
161 // an edit and then abandoned it and clicked a link on the page.) 160 // an edit and then abandoned it and clicked a link on the page.)
162 const bool visibly_changed_permanent_text = 161 const bool visibly_changed_permanent_text =
163 (permanent_text_ != new_permanent_text) && 162 (permanent_text_ != new_permanent_text) &&
164 (!user_input_in_progress_ || !has_focus_); 163 (!user_input_in_progress_ || !has_focus());
165 164
166 permanent_text_ = new_permanent_text; 165 permanent_text_ = new_permanent_text;
167 return visibly_changed_permanent_text; 166 return visibly_changed_permanent_text;
168 } 167 }
169 168
170 GURL OmniboxEditModel::PermanentURL() { 169 GURL OmniboxEditModel::PermanentURL() {
171 return URLFixerUpper::FixupURL(UTF16ToUTF8(permanent_text_), std::string()); 170 return URLFixerUpper::FixupURL(UTF16ToUTF8(permanent_text_), std::string());
172 } 171 }
173 172
174 void OmniboxEditModel::SetUserText(const string16& text) { 173 void OmniboxEditModel::SetUserText(const string16& text) {
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 429
431 void OmniboxEditModel::Revert() { 430 void OmniboxEditModel::Revert() {
432 SetInputInProgress(false); 431 SetInputInProgress(false);
433 paste_state_ = NONE; 432 paste_state_ = NONE;
434 InternalSetUserText(string16()); 433 InternalSetUserText(string16());
435 keyword_.clear(); 434 keyword_.clear();
436 is_keyword_hint_ = false; 435 is_keyword_hint_ = false;
437 has_temporary_text_ = false; 436 has_temporary_text_ = false;
438 is_temporary_text_set_by_instant_ = false; 437 is_temporary_text_set_by_instant_ = false;
439 view_->SetWindowTextAndCaretPos(permanent_text_, 438 view_->SetWindowTextAndCaretPos(permanent_text_,
440 has_focus_ ? permanent_text_.length() : 0, 439 has_focus() ? permanent_text_.length() : 0,
441 false, true); 440 false, true);
442 AutocompleteActionPredictor* action_predictor = 441 AutocompleteActionPredictor* action_predictor =
443 AutocompleteActionPredictorFactory::GetForProfile(profile_); 442 AutocompleteActionPredictorFactory::GetForProfile(profile_);
444 if (action_predictor) 443 if (action_predictor)
445 action_predictor->ClearTransitionalMatches(); 444 action_predictor->ClearTransitionalMatches();
446 } 445 }
447 446
448 void OmniboxEditModel::StartAutocomplete( 447 void OmniboxEditModel::StartAutocomplete(
449 bool has_selected_text, 448 bool has_selected_text,
450 bool prevent_inline_autocomplete) const { 449 bool prevent_inline_autocomplete) const {
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
706 view_->SetWindowTextAndCaretPos(window_text.c_str(), keyword_.length(), 705 view_->SetWindowTextAndCaretPos(window_text.c_str(), keyword_.length(),
707 false, true); 706 false, true);
708 } 707 }
709 } 708 }
710 709
711 const AutocompleteResult& OmniboxEditModel::result() const { 710 const AutocompleteResult& OmniboxEditModel::result() const {
712 return autocomplete_controller_->result(); 711 return autocomplete_controller_->result();
713 } 712 }
714 713
715 void OmniboxEditModel::OnSetFocus(bool control_down) { 714 void OmniboxEditModel::OnSetFocus(bool control_down) {
716 has_focus_ = true; 715 // If the omnibox lost focus while the caret was hidden and then regained
716 // focus, OnSetFocus() is called and should restore visibility. Note that
717 // focus can be regained without an accompanying call to
718 // OmniboxView::SetFocus(), e.g. by tabbing in.
719 SetFocusState(OMNIBOX_FOCUS_VISIBLE, OMNIBOX_FOCUS_CHANGE_EXPLICIT);
717 control_key_state_ = control_down ? DOWN_WITHOUT_CHANGE : UP; 720 control_key_state_ = control_down ? DOWN_WITHOUT_CHANGE : UP;
718 // Restore caret visibility whenever the user focuses back into the omnibox.
719 SetCaretVisibility(true);
720
721 if (InstantController* instant = controller_->GetInstant())
722 instant->OmniboxGotFocus();
723 721
724 content::WebContents* web_contents = controller_->GetWebContents(); 722 content::WebContents* web_contents = controller_->GetWebContents();
725 if (web_contents) { 723 if (web_contents) {
726 // TODO(jered): We may want to merge this into Start() and just call that 724 // TODO(jered): We may want to merge this into Start() and just call that
727 // here rather than having a special entry point for zero-suggest. Note 725 // here rather than having a special entry point for zero-suggest. Note
728 // that we avoid PermanentURL() here because it's not guaranteed to give us 726 // that we avoid PermanentURL() here because it's not guaranteed to give us
729 // the actual underlying current URL, e.g. if we're on the NTP and the 727 // the actual underlying current URL, e.g. if we're on the NTP and the
730 // |permanent_text_| is empty. 728 // |permanent_text_| is empty.
731 autocomplete_controller_->StartZeroSuggest(web_contents->GetURL(), 729 autocomplete_controller_->StartZeroSuggest(web_contents->GetURL(),
732 user_text_); 730 user_text_);
733 } 731 }
734 732
735 NotifySearchTabHelper(); 733 NotifySearchTabHelper();
736 } 734 }
737 735
738 void OmniboxEditModel::SetCaretVisibility(bool visible) { 736 void OmniboxEditModel::SetCaretVisibility(bool visible) {
739 if (has_focus_ && visible != is_caret_visible_) { 737 // Caret visibility only matters if the omnibox has focus.
740 is_caret_visible_ = visible; 738 if (focus_state_ != OMNIBOX_FOCUS_NONE) {
741 view_->ApplyCaretVisibility(); 739 SetFocusState(visible ? OMNIBOX_FOCUS_VISIBLE : OMNIBOX_FOCUS_INVISIBLE,
Peter Kasting 2012/12/11 19:20:50 I wonder if maybe we should just nuke SetCaretVisi
samarth 2012/12/12 01:11:26 That seems like overpromising. We'd have to put a
740 OMNIBOX_FOCUS_CHANGE_EXPLICIT);
742 } 741 }
743 } 742 }
744 743
745 void OmniboxEditModel::OnWillKillFocus(gfx::NativeView view_gaining_focus) { 744 void OmniboxEditModel::OnWillKillFocus(gfx::NativeView view_gaining_focus) {
746 SetInstantSuggestion(InstantSuggestion()); 745 SetInstantSuggestion(InstantSuggestion());
747 746
748 if (InstantController* instant = controller_->GetInstant()) 747 InstantController* instant = controller_->GetInstant();
749 instant->OmniboxLostFocus(view_gaining_focus); 748 if (instant) {
749 instant->OmniboxFocusChanged(OMNIBOX_FOCUS_NONE,
750 OMNIBOX_FOCUS_CHANGE_EXPLICIT,
751 view_gaining_focus);
752 }
750 753
751 // TODO(jered): Rip this out along with StartZeroSuggest. 754 // TODO(jered): Rip this out along with StartZeroSuggest.
752 autocomplete_controller_->StopZeroSuggest(); 755 autocomplete_controller_->StopZeroSuggest();
753 NotifySearchTabHelper(); 756 NotifySearchTabHelper();
754 } 757 }
755 758
756 void OmniboxEditModel::OnKillFocus() { 759 void OmniboxEditModel::OnKillFocus() {
757 has_focus_ = false; 760 // TODO(samarth): determine if it is safe to move the call to
761 // OmniboxFocusChanged() from OnWillKillFocus() to here, which would let us
762 // just call SetFocusState() to handle the state change.
763 focus_state_ = OMNIBOX_FOCUS_NONE;
758 control_key_state_ = UP; 764 control_key_state_ = UP;
759 paste_state_ = NONE; 765 paste_state_ = NONE;
760 } 766 }
761 767
762 bool OmniboxEditModel::OnEscapeKeyPressed() { 768 bool OmniboxEditModel::OnEscapeKeyPressed() {
763 if (has_temporary_text_) { 769 if (has_temporary_text_) {
764 AutocompleteMatch match; 770 AutocompleteMatch match;
765 InfoForCurrentSelection(&match, NULL); 771 InfoForCurrentSelection(&match, NULL);
766 if (match.destination_url != original_url_) { 772 if (match.destination_url != original_url_) {
767 RevertTemporaryText(true); 773 RevertTemporaryText(true);
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
945 // that replaced all the text, preserve that information; otherwise, if we've 951 // that replaced all the text, preserve that information; otherwise, if we've
946 // made some other edit, clear paste tracking. 952 // made some other edit, clear paste tracking.
947 if (paste_state_ == PASTING) 953 if (paste_state_ == PASTING)
948 paste_state_ = PASTED; 954 paste_state_ = PASTED;
949 else if (text_differs) 955 else if (text_differs)
950 paste_state_ = NONE; 956 paste_state_ = NONE;
951 957
952 // Restore caret visibility whenever the user changes text or selection in the 958 // Restore caret visibility whenever the user changes text or selection in the
953 // omnibox. 959 // omnibox.
954 if (text_differs || selection_differs) 960 if (text_differs || selection_differs)
955 SetCaretVisibility(true); 961 SetFocusState(OMNIBOX_FOCUS_VISIBLE, OMNIBOX_FOCUS_CHANGE_TYPING);
956 962
957 // Modifying the selection counts as accepting the autocompleted text. 963 // Modifying the selection counts as accepting the autocompleted text.
958 const bool user_text_changed = 964 const bool user_text_changed =
959 text_differs || (selection_differs && !inline_autocomplete_text_.empty()); 965 text_differs || (selection_differs && !inline_autocomplete_text_.empty());
960 966
961 // If something has changed while the control key is down, prevent 967 // If something has changed while the control key is down, prevent
962 // "ctrl-enter" until the control key is released. When we do this, we need 968 // "ctrl-enter" until the control key is released. When we do this, we need
963 // to update the popup if it's open, since the desired_tld will have changed. 969 // to update the popup if it's open, since the desired_tld will have changed.
964 if ((text_differs || selection_differs) && 970 if ((text_differs || selection_differs) &&
965 (control_key_state_ == DOWN_WITHOUT_CHANGE)) { 971 (control_key_state_ == DOWN_WITHOUT_CHANGE)) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1007 // 1013 //
1008 // If MaybeAcceptKeywordBySpace() accepts the keyword and returns true, that 1014 // If MaybeAcceptKeywordBySpace() accepts the keyword and returns true, that
1009 // will have updated our state already, so in that case we don't also return 1015 // will have updated our state already, so in that case we don't also return
1010 // true from this function. 1016 // true from this function.
1011 return !(text_differs && allow_keyword_ui_change && !just_deleted_text && 1017 return !(text_differs && allow_keyword_ui_change && !just_deleted_text &&
1012 no_selection && (selection_start == user_text_.length()) && 1018 no_selection && (selection_start == user_text_.length()) &&
1013 MaybeAcceptKeywordBySpace(user_text_)); 1019 MaybeAcceptKeywordBySpace(user_text_));
1014 } 1020 }
1015 1021
1016 void OmniboxEditModel::PopupBoundsChangedTo(const gfx::Rect& bounds) { 1022 void OmniboxEditModel::PopupBoundsChangedTo(const gfx::Rect& bounds) {
1017 if (InstantController* instant = controller_->GetInstant()) 1023 InstantController* instant = controller_->GetInstant();
1024 if (instant)
1018 instant->SetOmniboxBounds(bounds); 1025 instant->SetOmniboxBounds(bounds);
1019 } 1026 }
1020 1027
1021 void OmniboxEditModel::OnResultChanged(bool default_match_changed) { 1028 void OmniboxEditModel::OnResultChanged(bool default_match_changed) {
1022 const bool was_open = popup_->IsOpen(); 1029 const bool was_open = popup_->IsOpen();
1023 if (default_match_changed) { 1030 if (default_match_changed) {
1024 string16 inline_autocomplete_text; 1031 string16 inline_autocomplete_text;
1025 string16 keyword; 1032 string16 keyword;
1026 bool is_keyword_hint = false; 1033 bool is_keyword_hint = false;
1027 const AutocompleteResult& result = this->result(); 1034 const AutocompleteResult& result = this->result();
(...skipping 28 matching lines...) Expand all
1056 } else if (was_open) { 1063 } else if (was_open) {
1057 // Accepts the temporary text as the user text, because it makes little 1064 // Accepts the temporary text as the user text, because it makes little
1058 // sense to have temporary text when the popup is closed. 1065 // sense to have temporary text when the popup is closed.
1059 InternalSetUserText(UserTextFromDisplayText(view_->GetText())); 1066 InternalSetUserText(UserTextFromDisplayText(view_->GetText()));
1060 has_temporary_text_ = false; 1067 has_temporary_text_ = false;
1061 is_temporary_text_set_by_instant_ = false; 1068 is_temporary_text_set_by_instant_ = false;
1062 PopupBoundsChangedTo(gfx::Rect()); 1069 PopupBoundsChangedTo(gfx::Rect());
1063 NotifySearchTabHelper(); 1070 NotifySearchTabHelper();
1064 } 1071 }
1065 1072
1066 if (InstantController* instant = controller_->GetInstant()) 1073 InstantController* instant = controller_->GetInstant();
1074 if (instant)
1067 instant->HandleAutocompleteResults(*autocomplete_controller_->providers()); 1075 instant->HandleAutocompleteResults(*autocomplete_controller_->providers());
1068 } 1076 }
1069 1077
1070 bool OmniboxEditModel::query_in_progress() const { 1078 bool OmniboxEditModel::query_in_progress() const {
1071 return !autocomplete_controller_->done(); 1079 return !autocomplete_controller_->done();
1072 } 1080 }
1073 1081
1074 void OmniboxEditModel::InternalSetUserText(const string16& text) { 1082 void OmniboxEditModel::InternalSetUserText(const string16& text) {
1075 user_text_ = text; 1083 user_text_ = text;
1076 just_deleted_text_ = false; 1084 just_deleted_text_ = false;
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
1281 } 1289 }
1282 1290
1283 void OmniboxEditModel::ClassifyStringForPasteAndGo( 1291 void OmniboxEditModel::ClassifyStringForPasteAndGo(
1284 const string16& text, 1292 const string16& text,
1285 AutocompleteMatch* match, 1293 AutocompleteMatch* match,
1286 GURL* alternate_nav_url) const { 1294 GURL* alternate_nav_url) const {
1287 DCHECK(match); 1295 DCHECK(match);
1288 AutocompleteClassifierFactory::GetForProfile(profile_)->Classify(text, 1296 AutocompleteClassifierFactory::GetForProfile(profile_)->Classify(text,
1289 string16(), false, false, match, alternate_nav_url); 1297 string16(), false, false, match, alternate_nav_url);
1290 } 1298 }
1299
1300 void OmniboxEditModel::SetFocusState(OmniboxFocusState state,
1301 OmniboxFocusChangeReason reason) {
1302 if (state == focus_state_)
1303 return;
1304
1305 InstantController* instant = controller_->GetInstant();
1306 if (instant)
1307 instant->OmniboxFocusChanged(state, reason, NULL);
1308
1309 // Update state and notify view if the omnibox has focus and the caret
1310 // visibility changed.
1311 const bool was_caret_visible = is_caret_visible();
1312 focus_state_ = state;
1313 if (focus_state_ != OMNIBOX_FOCUS_NONE &&
1314 is_caret_visible() != was_caret_visible)
1315 view_->ApplyCaretVisibility();
1316 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698