OLD | NEW |
---|---|
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 "components/omnibox/browser/omnibox_edit_model.h" | 5 #include "components/omnibox/browser/omnibox_edit_model.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
64 const char kOmniboxUserTextClearedHistogram[] = "Omnibox.UserTextCleared"; | 64 const char kOmniboxUserTextClearedHistogram[] = "Omnibox.UserTextCleared"; |
65 | 65 |
66 enum UserTextClearedType { | 66 enum UserTextClearedType { |
67 OMNIBOX_USER_TEXT_CLEARED_BY_EDITING = 0, | 67 OMNIBOX_USER_TEXT_CLEARED_BY_EDITING = 0, |
68 OMNIBOX_USER_TEXT_CLEARED_WITH_ESCAPE = 1, | 68 OMNIBOX_USER_TEXT_CLEARED_WITH_ESCAPE = 1, |
69 OMNIBOX_USER_TEXT_CLEARED_NUM_OF_ITEMS, | 69 OMNIBOX_USER_TEXT_CLEARED_NUM_OF_ITEMS, |
70 }; | 70 }; |
71 | 71 |
72 // Histogram name which counts the number of times the user enters | 72 // Histogram name which counts the number of times the user enters |
73 // keyword hint mode and via what method. The possible values are listed | 73 // keyword hint mode and via what method. The possible values are listed |
74 // in the EnteredKeywordModeMethod enum which is defined in the .h file. | 74 // in the KeywordModeEntryMethod enum which is defined in the .h file. |
75 const char kEnteredKeywordModeHistogram[] = "Omnibox.EnteredKeywordMode"; | 75 const char kEnteredKeywordModeHistogram[] = "Omnibox.EnteredKeywordMode"; |
76 | 76 |
77 // Histogram name which counts the number of milliseconds a user takes | 77 // Histogram name which counts the number of milliseconds a user takes |
78 // between focusing and editing the omnibox. | 78 // between focusing and editing the omnibox. |
79 const char kFocusToEditTimeHistogram[] = "Omnibox.FocusToEditTime"; | 79 const char kFocusToEditTimeHistogram[] = "Omnibox.FocusToEditTime"; |
80 | 80 |
81 // Histogram name which counts the number of milliseconds a user takes | 81 // Histogram name which counts the number of milliseconds a user takes |
82 // between focusing and opening an omnibox match. | 82 // between focusing and opening an omnibox match. |
83 const char kFocusToOpenTimeHistogram[] = "Omnibox.FocusToOpenTimeAnyPopupState"; | 83 const char kFocusToOpenTimeHistogram[] = "Omnibox.FocusToOpenTimeAnyPopupState"; |
84 | 84 |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
142 } // namespace | 142 } // namespace |
143 | 143 |
144 | 144 |
145 // OmniboxEditModel::State ---------------------------------------------------- | 145 // OmniboxEditModel::State ---------------------------------------------------- |
146 | 146 |
147 OmniboxEditModel::State::State(bool user_input_in_progress, | 147 OmniboxEditModel::State::State(bool user_input_in_progress, |
148 const base::string16& user_text, | 148 const base::string16& user_text, |
149 const base::string16& gray_text, | 149 const base::string16& gray_text, |
150 const base::string16& keyword, | 150 const base::string16& keyword, |
151 bool is_keyword_hint, | 151 bool is_keyword_hint, |
152 KeywordModeEntryMethod keyword_mode_entry_method, | |
152 bool url_replacement_enabled, | 153 bool url_replacement_enabled, |
153 OmniboxFocusState focus_state, | 154 OmniboxFocusState focus_state, |
154 FocusSource focus_source, | 155 FocusSource focus_source, |
155 const AutocompleteInput& autocomplete_input) | 156 const AutocompleteInput& autocomplete_input) |
156 : user_input_in_progress(user_input_in_progress), | 157 : user_input_in_progress(user_input_in_progress), |
157 user_text(user_text), | 158 user_text(user_text), |
158 gray_text(gray_text), | 159 gray_text(gray_text), |
159 keyword(keyword), | 160 keyword(keyword), |
160 is_keyword_hint(is_keyword_hint), | 161 is_keyword_hint(is_keyword_hint), |
162 keyword_mode_entry_method(keyword_mode_entry_method), | |
161 url_replacement_enabled(url_replacement_enabled), | 163 url_replacement_enabled(url_replacement_enabled), |
162 focus_state(focus_state), | 164 focus_state(focus_state), |
163 focus_source(focus_source), | 165 focus_source(focus_source), |
164 autocomplete_input(autocomplete_input) { | 166 autocomplete_input(autocomplete_input) { |
165 } | 167 } |
166 | 168 |
167 OmniboxEditModel::State::State(const State& other) = default; | 169 OmniboxEditModel::State::State(const State& other) = default; |
168 | 170 |
169 OmniboxEditModel::State::~State() { | 171 OmniboxEditModel::State::~State() { |
170 } | 172 } |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
210 view_->SelectAll(true); | 212 view_->SelectAll(true); |
211 } else { | 213 } else { |
212 InternalSetUserText(display_text); | 214 InternalSetUserText(display_text); |
213 } | 215 } |
214 } | 216 } |
215 | 217 |
216 UMA_HISTOGRAM_BOOLEAN("Omnibox.SaveStateForTabSwitch.UserInputInProgress", | 218 UMA_HISTOGRAM_BOOLEAN("Omnibox.SaveStateForTabSwitch.UserInputInProgress", |
217 user_input_in_progress_); | 219 user_input_in_progress_); |
218 return State( | 220 return State( |
219 user_input_in_progress_, user_text_, view_->GetGrayTextAutocompletion(), | 221 user_input_in_progress_, user_text_, view_->GetGrayTextAutocompletion(), |
220 keyword_, is_keyword_hint_, | 222 keyword_, is_keyword_hint_, keyword_mode_entry_method_, |
221 controller_->GetToolbarModel()->url_replacement_enabled(), | 223 controller_->GetToolbarModel()->url_replacement_enabled(), |
222 focus_state_, focus_source_, input_); | 224 focus_state_, focus_source_, input_); |
223 } | 225 } |
224 | 226 |
225 void OmniboxEditModel::RestoreState(const State* state) { | 227 void OmniboxEditModel::RestoreState(const State* state) { |
226 // We need to update the permanent text correctly and revert the view | 228 // We need to update the permanent text correctly and revert the view |
227 // regardless of whether there is saved state. | 229 // regardless of whether there is saved state. |
228 bool url_replacement_enabled = !state || state->url_replacement_enabled; | 230 bool url_replacement_enabled = !state || state->url_replacement_enabled; |
229 controller_->GetToolbarModel()->set_url_replacement_enabled( | 231 controller_->GetToolbarModel()->set_url_replacement_enabled( |
230 url_replacement_enabled); | 232 url_replacement_enabled); |
231 permanent_text_ = controller_->GetToolbarModel()->GetText(); | 233 permanent_text_ = controller_->GetToolbarModel()->GetText(); |
232 // Don't muck with the search term replacement state, as we've just set it | 234 // Don't muck with the search term replacement state, as we've just set it |
233 // correctly. | 235 // correctly. |
234 view_->RevertWithoutResettingSearchTermReplacement(); | 236 view_->RevertWithoutResettingSearchTermReplacement(); |
235 // Restore the autocomplete controller's input, or clear it if this is a new | 237 // Restore the autocomplete controller's input, or clear it if this is a new |
236 // tab. | 238 // tab. |
237 input_ = state ? state->autocomplete_input : AutocompleteInput(); | 239 input_ = state ? state->autocomplete_input : AutocompleteInput(); |
238 if (!state) | 240 if (!state) |
239 return; | 241 return; |
240 | 242 |
241 SetFocusState(state->focus_state, OMNIBOX_FOCUS_CHANGE_TAB_SWITCH); | 243 SetFocusState(state->focus_state, OMNIBOX_FOCUS_CHANGE_TAB_SWITCH); |
242 focus_source_ = state->focus_source; | 244 focus_source_ = state->focus_source; |
243 // Restore any user editing. | 245 // Restore any user editing. |
244 if (state->user_input_in_progress) { | 246 if (state->user_input_in_progress) { |
245 // NOTE: Be sure and set keyword-related state AFTER invoking | 247 // NOTE: Be sure to set keyword-related state AFTER invoking |
246 // SetUserText(), as SetUserText() clears the keyword state. | 248 // SetUserText(), as SetUserText() clears the keyword state. |
247 view_->SetUserText(state->user_text, false); | 249 view_->SetUserText(state->user_text, false); |
248 keyword_ = state->keyword; | 250 keyword_ = state->keyword; |
249 is_keyword_hint_ = state->is_keyword_hint; | 251 is_keyword_hint_ = state->is_keyword_hint; |
252 keyword_mode_entry_method_ = state->keyword_mode_entry_method; | |
250 view_->SetGrayTextAutocompletion(state->gray_text); | 253 view_->SetGrayTextAutocompletion(state->gray_text); |
251 } | 254 } |
252 } | 255 } |
253 | 256 |
254 AutocompleteMatch OmniboxEditModel::CurrentMatch( | 257 AutocompleteMatch OmniboxEditModel::CurrentMatch( |
255 GURL* alternate_nav_url) const { | 258 GURL* alternate_nav_url) const { |
256 // If we have a valid match use it. Otherwise get one for the current text. | 259 // If we have a valid match use it. Otherwise get one for the current text. |
257 AutocompleteMatch match = omnibox_controller_->current_match(); | 260 AutocompleteMatch match = omnibox_controller_->current_match(); |
258 | 261 |
259 if (!match.destination_url.is_valid()) { | 262 if (!match.destination_url.is_valid()) { |
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
618 match.transition = ui::PAGE_TRANSITION_LINK; | 621 match.transition = ui::PAGE_TRANSITION_LINK; |
619 } | 622 } |
620 | 623 |
621 client_->OnInputAccepted(match); | 624 client_->OnInputAccepted(match); |
622 | 625 |
623 DCHECK(popup_model()); | 626 DCHECK(popup_model()); |
624 view_->OpenMatch(match, disposition, alternate_nav_url, base::string16(), | 627 view_->OpenMatch(match, disposition, alternate_nav_url, base::string16(), |
625 popup_model()->selected_line()); | 628 popup_model()->selected_line()); |
626 } | 629 } |
627 | 630 |
631 void OmniboxEditModel::EnterKeywordModeForDefaultSearchProvider( | |
632 KeywordModeEntryMethod entry_method) { | |
633 autocomplete_controller()->Stop(false); | |
634 | |
635 user_input_in_progress_ = true; | |
636 keyword_ = client_->GetTemplateURLService()-> | |
637 GetDefaultSearchProvider()->keyword(); | |
638 is_keyword_hint_ = false; | |
639 keyword_mode_entry_method_ = entry_method; | |
640 | |
641 StartAutocomplete(false, false, true); | |
642 | |
643 UMA_HISTOGRAM_ENUMERATION( | |
644 kEnteredKeywordModeHistogram, static_cast<int>(entry_method), | |
645 static_cast<int>(KeywordModeEntryMethod::NUM_ITEMS)); | |
646 } | |
647 | |
628 void OmniboxEditModel::OpenMatch(AutocompleteMatch match, | 648 void OmniboxEditModel::OpenMatch(AutocompleteMatch match, |
629 WindowOpenDisposition disposition, | 649 WindowOpenDisposition disposition, |
630 const GURL& alternate_nav_url, | 650 const GURL& alternate_nav_url, |
631 const base::string16& pasted_text, | 651 const base::string16& pasted_text, |
632 size_t index) { | 652 size_t index) { |
633 const base::TimeTicks& now(base::TimeTicks::Now()); | 653 const base::TimeTicks& now(base::TimeTicks::Now()); |
634 base::TimeDelta elapsed_time_since_user_first_modified_omnibox( | 654 base::TimeDelta elapsed_time_since_user_first_modified_omnibox( |
635 now - time_user_first_modified_omnibox_); | 655 now - time_user_first_modified_omnibox_); |
636 autocomplete_controller()->UpdateMatchDestinationURLWithQueryFormulationTime( | 656 autocomplete_controller()->UpdateMatchDestinationURLWithQueryFormulationTime( |
637 elapsed_time_since_user_first_modified_omnibox, &match); | 657 elapsed_time_since_user_first_modified_omnibox, &match); |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
776 match.transition | ui::PAGE_TRANSITION_FROM_ADDRESS_BAR)); | 796 match.transition | ui::PAGE_TRANSITION_FROM_ADDRESS_BAR)); |
777 if (observer && observer->HasSeenPendingLoad()) | 797 if (observer && observer->HasSeenPendingLoad()) |
778 ignore_result(observer.release()); // The observer will delete itself. | 798 ignore_result(observer.release()); // The observer will delete itself. |
779 } | 799 } |
780 | 800 |
781 BookmarkModel* bookmark_model = client_->GetBookmarkModel(); | 801 BookmarkModel* bookmark_model = client_->GetBookmarkModel(); |
782 if (bookmark_model && bookmark_model->IsBookmarked(match.destination_url)) | 802 if (bookmark_model && bookmark_model->IsBookmarked(match.destination_url)) |
783 client_->OnBookmarkLaunched(); | 803 client_->OnBookmarkLaunched(); |
784 } | 804 } |
785 | 805 |
786 bool OmniboxEditModel::AcceptKeyword(EnteredKeywordModeMethod entered_method) { | 806 bool OmniboxEditModel::AcceptKeyword( |
807 KeywordModeEntryMethod entry_method) { | |
787 DCHECK(is_keyword_hint_ && !keyword_.empty()); | 808 DCHECK(is_keyword_hint_ && !keyword_.empty()); |
788 | 809 |
789 autocomplete_controller()->Stop(false); | 810 autocomplete_controller()->Stop(false); |
811 | |
790 is_keyword_hint_ = false; | 812 is_keyword_hint_ = false; |
813 keyword_mode_entry_method_ = entry_method; | |
814 user_text_ = MaybeStripKeyword(user_text_); | |
791 | 815 |
792 user_text_ = MaybeStripKeyword(user_text_); | 816 user_text_ = MaybeStripKeyword(user_text_); |
793 | 817 |
794 if (popup_model() && popup_model()->IsOpen()) | 818 if (popup_model() && popup_model()->IsOpen()) |
795 popup_model()->SetSelectedLineState(OmniboxPopupModel::KEYWORD); | 819 popup_model()->SetSelectedLineState(OmniboxPopupModel::KEYWORD); |
796 else | 820 else |
797 StartAutocomplete(false, true, true); | 821 StartAutocomplete(false, true, true); |
798 | 822 |
799 // When entering keyword mode via tab, the new text to show is whatever the | 823 // When entering keyword mode via tab, the new text to show is whatever the |
800 // newly-selected match in the dropdown is. When entering via space, however, | 824 // newly-selected match in the dropdown is. When entering via space, however, |
801 // we should make sure to use the actual |user_text_| as the basis for the new | 825 // we should make sure to use the actual |user_text_| as the basis for the new |
802 // text. This ensures that if the user types "<keyword><space>" and the | 826 // text. This ensures that if the user types "<keyword><space>" and the |
803 // default match would have inline autocompleted a further string (e.g. | 827 // default match would have inline autocompleted a further string (e.g. |
804 // because there's a past multi-word search beginning with this keyword), the | 828 // because there's a past multi-word search beginning with this keyword), the |
805 // inline autocompletion doesn't get filled in as the keyword search query | 829 // inline autocompletion doesn't get filled in as the keyword search query |
806 // text. | 830 // text. |
807 // | 831 // |
808 // We also treat tabbing into keyword mode like tabbing through the popup in | 832 // We also treat tabbing into keyword mode like tabbing through the popup in |
809 // that we set |has_temporary_text_|, whereas pressing space is treated like | 833 // that we set |has_temporary_text_|, whereas pressing space is treated like |
810 // a new keystroke that changes the current match instead of overlaying it | 834 // a new keystroke that changes the current match instead of overlaying it |
811 // with a temporary one. This is important because rerunning autocomplete | 835 // with a temporary one. This is important because rerunning autocomplete |
812 // after the user pressed space, which will have happened just before reaching | 836 // after the user pressed space, which will have happened just before reaching |
813 // here, may have generated a new match, which the user won't actually see and | 837 // here, may have generated a new match, which the user won't actually see and |
814 // which we don't want to switch back to when existing keyword mode; see | 838 // which we don't want to switch back to when existing keyword mode; see |
815 // comments in ClearKeyword(). | 839 // comments in ClearKeyword(). |
816 if (entered_method == ENTERED_KEYWORD_MODE_VIA_TAB) { | 840 if (entry_method == KeywordModeEntryMethod::TAB) { |
817 // Ensure the current selection is saved before showing keyword mode | 841 // Ensure the current selection is saved before showing keyword mode |
818 // so that moving to another line and then reverting the text will restore | 842 // so that moving to another line and then reverting the text will restore |
819 // the current state properly. | 843 // the current state properly. |
820 bool save_original_selection = !has_temporary_text_; | 844 bool save_original_selection = !has_temporary_text_; |
821 has_temporary_text_ = true; | 845 has_temporary_text_ = true; |
822 const AutocompleteMatch& match = CurrentMatch(NULL); | 846 const AutocompleteMatch& match = CurrentMatch(NULL); |
823 original_url_ = match.destination_url; | 847 original_url_ = match.destination_url; |
824 view_->OnTemporaryTextMaybeChanged( | 848 view_->OnTemporaryTextMaybeChanged( |
825 MaybeStripKeyword(match.fill_into_edit), save_original_selection, | 849 MaybeStripKeyword(match.fill_into_edit), save_original_selection, |
826 true); | 850 true); |
827 } else { | 851 } else { |
828 view_->OnTemporaryTextMaybeChanged(user_text_, false, true); | 852 view_->OnTemporaryTextMaybeChanged(user_text_, false, true); |
829 } | 853 } |
830 | 854 |
831 base::RecordAction(base::UserMetricsAction("AcceptedKeywordHint")); | 855 base::RecordAction(base::UserMetricsAction("AcceptedKeywordHint")); |
832 UMA_HISTOGRAM_ENUMERATION(kEnteredKeywordModeHistogram, entered_method, | 856 UMA_HISTOGRAM_ENUMERATION( |
833 ENTERED_KEYWORD_MODE_NUM_ITEMS); | 857 kEnteredKeywordModeHistogram, static_cast<int>(entry_method), |
858 static_cast<int>(KeywordModeEntryMethod::NUM_ITEMS)); | |
834 | 859 |
835 return true; | 860 return true; |
836 } | 861 } |
837 | 862 |
838 void OmniboxEditModel::AcceptTemporaryTextAsUserText() { | 863 void OmniboxEditModel::AcceptTemporaryTextAsUserText() { |
839 InternalSetUserText(view_->GetText()); | 864 InternalSetUserText(view_->GetText()); |
840 has_temporary_text_ = false; | 865 has_temporary_text_ = false; |
841 | 866 |
842 if (user_input_in_progress_ || !in_revert_) | 867 if (user_input_in_progress_ || !in_revert_) |
843 client_->OnInputStateChanged(); | 868 client_->OnInputStateChanged(); |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
907 // without re-enabling keyword mode. The common case is state 3, where | 932 // without re-enabling keyword mode. The common case is state 3, where |
908 // the user entered keyword mode unintentionally, so backspacing | 933 // the user entered keyword mode unintentionally, so backspacing |
909 // immediately out of keyword mode should keep the space. In states 1 and | 934 // immediately out of keyword mode should keep the space. In states 1 and |
910 // 2, having the space is "safer" behavior. For instance, if the user types | 935 // 2, having the space is "safer" behavior. For instance, if the user types |
911 // "google.com f" or "google.com<tab>f" in the omnibox, moves the cursor to | 936 // "google.com f" or "google.com<tab>f" in the omnibox, moves the cursor to |
912 // the left, and presses backspace to leave keyword mode (state 1), it's | 937 // the left, and presses backspace to leave keyword mode (state 1), it's |
913 // better to have the space because it may be what the user wanted. The | 938 // better to have the space because it may be what the user wanted. The |
914 // user can easily delete it. On the other hand, if there is no space and | 939 // user can easily delete it. On the other hand, if there is no space and |
915 // the user wants it, it's more work to add because typing the space will | 940 // the user wants it, it's more work to add because typing the space will |
916 // enter keyword mode, which then the user would have to leave again. | 941 // enter keyword mode, which then the user would have to leave again. |
917 const base::string16 window_text = | 942 |
918 keyword_ + base::ASCIIToUTF16(" ") + view_->GetText(); | 943 // If we entered keyword mode in a special way like using a keyboard |
919 view_->SetWindowTextAndCaretPos(window_text.c_str(), keyword_.length() + 1, | 944 // shortcut or typing a question mark in a blank omnibox, don't restore the |
920 false, false); | 945 // keyword. Instead, restore the question mark iff the user originally |
946 // typed one. | |
947 base::string16 prefix; | |
948 if (keyword_mode_entry_method_ == KeywordModeEntryMethod::QUESTION_MARK) | |
949 prefix = base::ASCIIToUTF16("?"); | |
950 else if (keyword_mode_entry_method_ != | |
951 KeywordModeEntryMethod::KEYBOARD_SHORTCUT) | |
952 prefix = keyword_ + base::ASCIIToUTF16(" "); | |
953 | |
921 keyword_.clear(); | 954 keyword_.clear(); |
922 is_keyword_hint_ = false; | 955 is_keyword_hint_ = false; |
956 | |
957 view_->SetWindowTextAndCaretPos(prefix + view_->GetText(), prefix.length(), | |
958 false, false); | |
959 | |
923 view_->OnAfterPossibleChange(false); | 960 view_->OnAfterPossibleChange(false); |
961 StartAutocomplete(false, false, false); | |
Tom (Use chromium acct)
2016/05/18 23:58:36
If I remove StartAutocomplete here, I get bad beha
Peter Kasting
2016/05/21 00:01:01
Maybe the right fix here is that the popup should
Tom (Use chromium acct)
2016/05/27 22:12:07
Well, we would want the popup to remain open if th
Peter Kasting
2016/05/27 22:24:04
Right, that's why I said "runs autocomplete only i
Tom (Use chromium acct)
2016/05/27 22:42:47
I tested this out already. Even if we do this, we
| |
924 } | 962 } |
925 } | 963 } |
926 | 964 |
927 void OmniboxEditModel::OnSetFocus(bool control_down) { | 965 void OmniboxEditModel::OnSetFocus(bool control_down) { |
928 last_omnibox_focus_ = base::TimeTicks::Now(); | 966 last_omnibox_focus_ = base::TimeTicks::Now(); |
929 user_input_since_focus_ = false; | 967 user_input_since_focus_ = false; |
930 | 968 |
931 // If the omnibox lost focus while the caret was hidden and then regained | 969 // If the omnibox lost focus while the caret was hidden and then regained |
932 // focus, OnSetFocus() is called and should restore visibility. Note that | 970 // focus, OnSetFocus() is called and should restore visibility. Note that |
933 // focus can be regained without an accompanying call to | 971 // focus can be regained without an accompanying call to |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1152 if (call_controller_onchanged) | 1190 if (call_controller_onchanged) |
1153 OnChanged(); | 1191 OnChanged(); |
1154 } | 1192 } |
1155 | 1193 |
1156 bool OmniboxEditModel::OnAfterPossibleChange(const base::string16& old_text, | 1194 bool OmniboxEditModel::OnAfterPossibleChange(const base::string16& old_text, |
1157 const base::string16& new_text, | 1195 const base::string16& new_text, |
1158 size_t selection_start, | 1196 size_t selection_start, |
1159 size_t selection_end, | 1197 size_t selection_end, |
1160 bool selection_differs, | 1198 bool selection_differs, |
1161 bool text_differs, | 1199 bool text_differs, |
1200 bool keyword_differs, | |
1162 bool just_deleted_text, | 1201 bool just_deleted_text, |
1163 bool allow_keyword_ui_change) { | 1202 bool allow_keyword_ui_change) { |
1164 // Update the paste state as appropriate: if we're just finishing a paste | 1203 // Update the paste state as appropriate: if we're just finishing a paste |
1165 // that replaced all the text, preserve that information; otherwise, if we've | 1204 // that replaced all the text, preserve that information; otherwise, if we've |
1166 // made some other edit, clear paste tracking. | 1205 // made some other edit, clear paste tracking. |
1167 if (paste_state_ == PASTING) | 1206 if (paste_state_ == PASTING) |
1168 paste_state_ = PASTED; | 1207 paste_state_ = PASTED; |
1169 else if (text_differs) | 1208 else if (text_differs) |
1170 paste_state_ = NONE; | 1209 paste_state_ = NONE; |
1171 | 1210 |
(...skipping 19 matching lines...) Expand all Loading... | |
1191 const bool user_text_changed = | 1230 const bool user_text_changed = |
1192 text_differs || (selection_differs && !inline_autocomplete_text_.empty()); | 1231 text_differs || (selection_differs && !inline_autocomplete_text_.empty()); |
1193 | 1232 |
1194 // If something has changed while the control key is down, prevent | 1233 // If something has changed while the control key is down, prevent |
1195 // "ctrl-enter" until the control key is released. | 1234 // "ctrl-enter" until the control key is released. |
1196 if ((text_differs || selection_differs) && | 1235 if ((text_differs || selection_differs) && |
1197 (control_key_state_ == DOWN_WITHOUT_CHANGE)) | 1236 (control_key_state_ == DOWN_WITHOUT_CHANGE)) |
1198 control_key_state_ = DOWN_WITH_CHANGE; | 1237 control_key_state_ = DOWN_WITH_CHANGE; |
1199 | 1238 |
1200 if (!user_text_changed) | 1239 if (!user_text_changed) |
1201 return false; | 1240 return keyword_differs; |
1202 | 1241 |
1203 // If the user text has not changed, we do not want to change the model's | 1242 // If the user text has not changed, we do not want to change the model's |
1204 // state associated with the text. Otherwise, we can get surprising behavior | 1243 // state associated with the text. Otherwise, we can get surprising behavior |
1205 // where the autocompleted text unexpectedly reappears, e.g. crbug.com/55983 | 1244 // where the autocompleted text unexpectedly reappears, e.g. crbug.com/55983 |
1206 InternalSetUserText(new_text); | 1245 InternalSetUserText(new_text); |
1207 has_temporary_text_ = false; | 1246 has_temporary_text_ = false; |
1208 | 1247 |
1209 // Track when the user has deleted text so we won't allow inline | 1248 // Track when the user has deleted text so we won't allow inline |
1210 // autocomplete. | 1249 // autocomplete. |
1211 just_deleted_text_ = just_deleted_text; | 1250 just_deleted_text_ = just_deleted_text; |
(...skipping 14 matching lines...) Expand all Loading... | |
1226 // if the user hit space in mid-string after a keyword. | 1265 // if the user hit space in mid-string after a keyword. |
1227 // |allow_exact_keyword_match_| will be used by StartAutocomplete() method, | 1266 // |allow_exact_keyword_match_| will be used by StartAutocomplete() method, |
1228 // which will be called by |view_->UpdatePopup()|; so after that returns we | 1267 // which will be called by |view_->UpdatePopup()|; so after that returns we |
1229 // can safely reset this flag. | 1268 // can safely reset this flag. |
1230 allow_exact_keyword_match_ = text_differs && allow_keyword_ui_change && | 1269 allow_exact_keyword_match_ = text_differs && allow_keyword_ui_change && |
1231 !just_deleted_text && no_selection && | 1270 !just_deleted_text && no_selection && |
1232 CreatedKeywordSearchByInsertingSpaceInMiddle(old_text, user_text_, | 1271 CreatedKeywordSearchByInsertingSpaceInMiddle(old_text, user_text_, |
1233 selection_start); | 1272 selection_start); |
1234 view_->UpdatePopup(); | 1273 view_->UpdatePopup(); |
1235 if (allow_exact_keyword_match_) { | 1274 if (allow_exact_keyword_match_) { |
1236 UMA_HISTOGRAM_ENUMERATION(kEnteredKeywordModeHistogram, | 1275 keyword_mode_entry_method_ = KeywordModeEntryMethod::SPACE_IN_MIDDLE; |
1237 ENTERED_KEYWORD_MODE_VIA_SPACE_IN_MIDDLE, | 1276 UMA_HISTOGRAM_ENUMERATION( |
1238 ENTERED_KEYWORD_MODE_NUM_ITEMS); | 1277 kEnteredKeywordModeHistogram, |
1278 static_cast<int>(KeywordModeEntryMethod::SPACE_IN_MIDDLE), | |
1279 static_cast<int>(KeywordModeEntryMethod::NUM_ITEMS)); | |
1239 allow_exact_keyword_match_ = false; | 1280 allow_exact_keyword_match_ = false; |
1240 } | 1281 } |
1241 | 1282 |
1242 // Change to keyword mode if the user is now pressing space after a keyword | 1283 if (text_differs && allow_keyword_ui_change && !just_deleted_text && |
1243 // name. Note that if this is the case, then even if there was no keyword | 1284 no_selection && !is_keyword_selected()) { |
1244 // hint when we entered this function (e.g. if the user has used space to | 1285 // If the user input a "?" at the beginning of the text, put them into |
1245 // replace some selected text that was adjoined to this keyword), there will | 1286 // keyword mode for their default search provider. |
1246 // be one now because of the call to UpdatePopup() above; so it's safe for | 1287 if (selection_start == 1 && user_text_[0] == '?') { |
1247 // MaybeAcceptKeywordBySpace() to look at |keyword_| and |is_keyword_hint_| to | 1288 view_->SetUserText(user_text_.substr(1)); |
1248 // determine what keyword, if any, is applicable. | 1289 EnterKeywordModeForDefaultSearchProvider( |
1249 // | 1290 KeywordModeEntryMethod::QUESTION_MARK); |
Tom (Use chromium acct)
2016/05/18 23:58:36
If I type "abc" in the omnibox, move the cursor to
Peter Kasting
2016/05/21 00:01:01
Yes.
Tom (Use chromium acct)
2016/05/27 22:12:07
Done.
| |
1250 // If MaybeAcceptKeywordBySpace() accepts the keyword and returns true, that | 1291 return false; |
1251 // will have updated our state already, so in that case we don't also return | 1292 } |
1252 // true from this function. | 1293 |
1253 return !(text_differs && allow_keyword_ui_change && !just_deleted_text && | 1294 // Change to keyword mode if the user is now pressing space after a keyword |
1254 no_selection && (selection_start == user_text_.length()) && | 1295 // name. Note that if this is the case, then even if there was no keyword |
1255 MaybeAcceptKeywordBySpace(user_text_)); | 1296 // hint when we entered this function (e.g. if the user has used space to |
1297 // replace some selected text that was adjoined to this keyword), there will | |
1298 // be one now because of the call to UpdatePopup() above; so it's safe for | |
1299 // MaybeAcceptKeywordBySpace() to look at |keyword_| and |is_keyword_hint_| | |
1300 // to determine what keyword, if any, is applicable. | |
1301 // | |
1302 // If MaybeAcceptKeywordBySpace() accepts the keyword and returns true, that | |
1303 // will have updated our state already, so in that case we don't also return | |
1304 // true from this function. | |
1305 return !(selection_start == user_text_.length() && | |
1306 MaybeAcceptKeywordBySpace(user_text_)); | |
1307 } | |
1308 return true; | |
1256 } | 1309 } |
1257 | 1310 |
1258 // TODO(beaudoin): Merge OnPopupDataChanged with this method once the popup | 1311 // TODO(beaudoin): Merge OnPopupDataChanged with this method once the popup |
1259 // handling has completely migrated to omnibox_controller. | 1312 // handling has completely migrated to omnibox_controller. |
1260 void OmniboxEditModel::OnCurrentMatchChanged() { | 1313 void OmniboxEditModel::OnCurrentMatchChanged() { |
1261 has_temporary_text_ = false; | 1314 has_temporary_text_ = false; |
1262 | 1315 |
1263 const AutocompleteMatch& match = omnibox_controller_->current_match(); | 1316 const AutocompleteMatch& match = omnibox_controller_->current_match(); |
1264 | 1317 |
1265 client_->OnCurrentMatchChanged(match); | 1318 client_->OnCurrentMatchChanged(match); |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1373 view_->OnRevertTemporaryText(); | 1426 view_->OnRevertTemporaryText(); |
1374 } | 1427 } |
1375 | 1428 |
1376 bool OmniboxEditModel::MaybeAcceptKeywordBySpace( | 1429 bool OmniboxEditModel::MaybeAcceptKeywordBySpace( |
1377 const base::string16& new_text) { | 1430 const base::string16& new_text) { |
1378 size_t keyword_length = new_text.length() - 1; | 1431 size_t keyword_length = new_text.length() - 1; |
1379 return (paste_state_ == NONE) && is_keyword_hint_ && | 1432 return (paste_state_ == NONE) && is_keyword_hint_ && |
1380 (keyword_.length() == keyword_length) && | 1433 (keyword_.length() == keyword_length) && |
1381 IsSpaceCharForAcceptingKeyword(new_text[keyword_length]) && | 1434 IsSpaceCharForAcceptingKeyword(new_text[keyword_length]) && |
1382 !new_text.compare(0, keyword_length, keyword_, 0, keyword_length) && | 1435 !new_text.compare(0, keyword_length, keyword_, 0, keyword_length) && |
1383 AcceptKeyword(ENTERED_KEYWORD_MODE_VIA_SPACE_AT_END); | 1436 AcceptKeyword(KeywordModeEntryMethod::SPACE_AT_END); |
1384 } | 1437 } |
1385 | 1438 |
1386 bool OmniboxEditModel::CreatedKeywordSearchByInsertingSpaceInMiddle( | 1439 bool OmniboxEditModel::CreatedKeywordSearchByInsertingSpaceInMiddle( |
1387 const base::string16& old_text, | 1440 const base::string16& old_text, |
1388 const base::string16& new_text, | 1441 const base::string16& new_text, |
1389 size_t caret_position) const { | 1442 size_t caret_position) const { |
1390 DCHECK_GE(new_text.length(), caret_position); | 1443 DCHECK_GE(new_text.length(), caret_position); |
1391 | 1444 |
1392 // Check simple conditions first. | 1445 // Check simple conditions first. |
1393 if ((paste_state_ != NONE) || (caret_position < 2) || | 1446 if ((paste_state_ != NONE) || (caret_position < 2) || |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1467 // Update state and notify view if the omnibox has focus and the caret | 1520 // Update state and notify view if the omnibox has focus and the caret |
1468 // visibility changed. | 1521 // visibility changed. |
1469 const bool was_caret_visible = is_caret_visible(); | 1522 const bool was_caret_visible = is_caret_visible(); |
1470 focus_state_ = state; | 1523 focus_state_ = state; |
1471 if (focus_state_ != OMNIBOX_FOCUS_NONE && | 1524 if (focus_state_ != OMNIBOX_FOCUS_NONE && |
1472 is_caret_visible() != was_caret_visible) | 1525 is_caret_visible() != was_caret_visible) |
1473 view_->ApplyCaretVisibility(); | 1526 view_->ApplyCaretVisibility(); |
1474 | 1527 |
1475 client_->OnFocusChanged(focus_state_, reason); | 1528 client_->OnFocusChanged(focus_state_, reason); |
1476 } | 1529 } |
OLD | NEW |