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 "chrome/browser/ui/omnibox/omnibox_edit_model.h" | 5 #include "chrome/browser/ui/omnibox/omnibox_edit_model.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/auto_reset.h" | 10 #include "base/auto_reset.h" |
(...skipping 884 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
895 DCHECK(is_keyword_hint_ && !keyword_.empty()); | 895 DCHECK(is_keyword_hint_ && !keyword_.empty()); |
896 | 896 |
897 autocomplete_controller()->Stop(false); | 897 autocomplete_controller()->Stop(false); |
898 is_keyword_hint_ = false; | 898 is_keyword_hint_ = false; |
899 | 899 |
900 if (popup_model() && popup_model()->IsOpen()) | 900 if (popup_model() && popup_model()->IsOpen()) |
901 popup_model()->SetSelectedLineState(OmniboxPopupModel::KEYWORD); | 901 popup_model()->SetSelectedLineState(OmniboxPopupModel::KEYWORD); |
902 else | 902 else |
903 StartAutocomplete(false, true, true); | 903 StartAutocomplete(false, true, true); |
904 | 904 |
905 // Ensure the current selection is saved before showing keyword mode | 905 // When entering keyword mode via tab, the new text to show is whatever the |
906 // so that moving to another line and then reverting the text will restore | 906 // newly-selected match in the dropdown is. When entering via space, however, |
907 // the current state properly. | 907 // we should make sure to use the actual |user_text_| as the basis for the new |
908 bool save_original_selection = !has_temporary_text_; | 908 // text. This ensures that if the user types "<keyword><space>" and the |
909 has_temporary_text_ = true; | 909 // default match would have inline autocompleted a further string (e.g. |
910 const AutocompleteMatch& match = CurrentMatch(NULL); | 910 // because there's a past multi-word search beginning with this keyword), the |
911 original_url_ = match.destination_url; | 911 // inline autocompletion doesn't get filled in as the keyword search query |
912 view_->OnTemporaryTextMaybeChanged( | 912 // text. |
913 DisplayTextFromUserText(match.fill_into_edit), | 913 // |
914 save_original_selection, true); | 914 // We also treat tabbing into keyword mode like tabbing through the popup in |
| 915 // that we set |has_temporary_text_|, whereas pressing space is treated like |
| 916 // a new keystroke that changes the current match instead of overlaying it |
| 917 // with a temporary one. This is important because rerunning autocomplete |
| 918 // after the user pressed space, which will have happened just before reaching |
| 919 // here, may have generated a new match, which the user won't actually see and |
| 920 // which we don't want to switch back to when existing keyword mode; see |
| 921 // comments in ClearKeyword(). |
| 922 if (entered_method == ENTERED_KEYWORD_MODE_VIA_TAB) { |
| 923 // Ensure the current selection is saved before showing keyword mode |
| 924 // so that moving to another line and then reverting the text will restore |
| 925 // the current state properly. |
| 926 bool save_original_selection = !has_temporary_text_; |
| 927 has_temporary_text_ = true; |
| 928 const AutocompleteMatch& match = CurrentMatch(NULL); |
| 929 original_url_ = match.destination_url; |
| 930 view_->OnTemporaryTextMaybeChanged( |
| 931 DisplayTextFromUserText(match.fill_into_edit), |
| 932 save_original_selection, true); |
| 933 } else { |
| 934 view_->OnTemporaryTextMaybeChanged(DisplayTextFromUserText(user_text_), |
| 935 false, true); |
| 936 } |
915 | 937 |
916 view_->UpdatePlaceholderText(); | 938 view_->UpdatePlaceholderText(); |
917 | 939 |
918 content::RecordAction(base::UserMetricsAction("AcceptedKeywordHint")); | 940 content::RecordAction(base::UserMetricsAction("AcceptedKeywordHint")); |
919 UMA_HISTOGRAM_ENUMERATION(kEnteredKeywordModeHistogram, entered_method, | 941 UMA_HISTOGRAM_ENUMERATION(kEnteredKeywordModeHistogram, entered_method, |
920 ENTERED_KEYWORD_MODE_NUM_ITEMS); | 942 ENTERED_KEYWORD_MODE_NUM_ITEMS); |
921 | 943 |
922 return true; | 944 return true; |
923 } | 945 } |
924 | 946 |
925 void OmniboxEditModel::AcceptTemporaryTextAsUserText() { | 947 void OmniboxEditModel::AcceptTemporaryTextAsUserText() { |
926 InternalSetUserText(UserTextFromDisplayText(view_->GetText())); | 948 InternalSetUserText(UserTextFromDisplayText(view_->GetText())); |
927 has_temporary_text_ = false; | 949 has_temporary_text_ = false; |
928 | 950 |
929 if (user_input_in_progress_ || !in_revert_) | 951 if (user_input_in_progress_ || !in_revert_) |
930 delegate_->OnInputStateChanged(); | 952 delegate_->OnInputStateChanged(); |
931 } | 953 } |
932 | 954 |
933 void OmniboxEditModel::ClearKeyword() { | 955 void OmniboxEditModel::ClearKeyword() { |
934 autocomplete_controller()->Stop(false); | 956 autocomplete_controller()->Stop(false); |
935 omnibox_controller_->ClearPopupKeywordMode(); | 957 omnibox_controller_->ClearPopupKeywordMode(); |
936 | 958 |
937 const base::string16 window_text(keyword_ + view_->GetText()); | 959 const base::string16 window_text(keyword_ + view_->GetText()); |
938 | 960 |
939 // Only reset the result if the edit text has changed since the | 961 // If we've tabbed into keyword mode and haven't done anything else, |
940 // keyword was accepted, or if the popup is closed. | 962 // |has_temporary_text_| will be true, and we should just revert into keyword |
941 if (!just_deleted_text_ && view_->GetText().empty() && popup_model() && | 963 // hint mode; otherwise we do a more complete state update/revert via |
942 popup_model()->IsOpen()) { | 964 // OnBefore/AfterPossibleChange(). |
| 965 // |
| 966 // If we were to do the "complete state revert" all the time, then in cases |
| 967 // where our associated keyword match is in the middle of the popup instead of |
| 968 // on the first line, tabbing into it and then hitting shift-tab would reset |
| 969 // the entire popup contents, and we'd wind up with the first line selected. |
| 970 // |
| 971 // If we were instead to "just switch back to keyword hint mode" all the time, |
| 972 // we could wind up with strange state in some cases. For example, if a user |
| 973 // has a keyword named "x", an inline-autocompletable history site "xyz.com", |
| 974 // and a lower-ranked inline-autocompletable search "x y", then typing "x" |
| 975 // will inline autocomplete to "xyz.com", hitting space will toggle into |
| 976 // keyword mode, but then hitting backspace might wind up with the default |
| 977 // match as the "x y" search, due to the particulars of how we re-run |
| 978 // autocomplete for "x " before toggling into keyword mode to begin with. |
| 979 if (has_temporary_text_) { |
943 is_keyword_hint_ = true; | 980 is_keyword_hint_ = true; |
944 view_->SetWindowTextAndCaretPos(window_text.c_str(), keyword_.length(), | 981 view_->SetWindowTextAndCaretPos(window_text.c_str(), keyword_.length(), |
945 false, true); | 982 false, true); |
946 } else { | 983 } else { |
947 view_->OnBeforePossibleChange(); | 984 view_->OnBeforePossibleChange(); |
948 view_->SetWindowTextAndCaretPos(window_text.c_str(), keyword_.length(), | 985 view_->SetWindowTextAndCaretPos(window_text.c_str(), keyword_.length(), |
949 false, false); | 986 false, false); |
950 keyword_.clear(); | 987 keyword_.clear(); |
951 is_keyword_hint_ = false; | 988 is_keyword_hint_ = false; |
952 view_->OnAfterPossibleChange(); | 989 view_->OnAfterPossibleChange(); |
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1405 | 1442 |
1406 if (revert_popup && popup_model()) | 1443 if (revert_popup && popup_model()) |
1407 popup_model()->ResetToDefaultMatch(); | 1444 popup_model()->ResetToDefaultMatch(); |
1408 view_->OnRevertTemporaryText(); | 1445 view_->OnRevertTemporaryText(); |
1409 } | 1446 } |
1410 | 1447 |
1411 bool OmniboxEditModel::MaybeAcceptKeywordBySpace( | 1448 bool OmniboxEditModel::MaybeAcceptKeywordBySpace( |
1412 const base::string16& new_text) { | 1449 const base::string16& new_text) { |
1413 size_t keyword_length = new_text.length() - 1; | 1450 size_t keyword_length = new_text.length() - 1; |
1414 return (paste_state_ == NONE) && is_keyword_hint_ && | 1451 return (paste_state_ == NONE) && is_keyword_hint_ && |
1415 inline_autocomplete_text_.empty() && | |
1416 (keyword_.length() == keyword_length) && | 1452 (keyword_.length() == keyword_length) && |
1417 IsSpaceCharForAcceptingKeyword(new_text[keyword_length]) && | 1453 IsSpaceCharForAcceptingKeyword(new_text[keyword_length]) && |
1418 !new_text.compare(0, keyword_length, keyword_, 0, keyword_length) && | 1454 !new_text.compare(0, keyword_length, keyword_, 0, keyword_length) && |
1419 AcceptKeyword(ENTERED_KEYWORD_MODE_VIA_SPACE_AT_END); | 1455 AcceptKeyword(ENTERED_KEYWORD_MODE_VIA_SPACE_AT_END); |
1420 } | 1456 } |
1421 | 1457 |
1422 bool OmniboxEditModel::CreatedKeywordSearchByInsertingSpaceInMiddle( | 1458 bool OmniboxEditModel::CreatedKeywordSearchByInsertingSpaceInMiddle( |
1423 const base::string16& old_text, | 1459 const base::string16& old_text, |
1424 const base::string16& new_text, | 1460 const base::string16& new_text, |
1425 size_t caret_position) const { | 1461 size_t caret_position) const { |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1503 // Update state and notify view if the omnibox has focus and the caret | 1539 // Update state and notify view if the omnibox has focus and the caret |
1504 // visibility changed. | 1540 // visibility changed. |
1505 const bool was_caret_visible = is_caret_visible(); | 1541 const bool was_caret_visible = is_caret_visible(); |
1506 focus_state_ = state; | 1542 focus_state_ = state; |
1507 if (focus_state_ != OMNIBOX_FOCUS_NONE && | 1543 if (focus_state_ != OMNIBOX_FOCUS_NONE && |
1508 is_caret_visible() != was_caret_visible) | 1544 is_caret_visible() != was_caret_visible) |
1509 view_->ApplyCaretVisibility(); | 1545 view_->ApplyCaretVisibility(); |
1510 | 1546 |
1511 delegate_->OnFocusChanged(focus_state_, reason); | 1547 delegate_->OnFocusChanged(focus_state_, reason); |
1512 } | 1548 } |
OLD | NEW |