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/autocomplete/autocomplete_edit.h" | 5 #include "chrome/browser/autocomplete/autocomplete_edit.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
406 has_focus_ ? permanent_text_.length() : 0); | 406 has_focus_ ? permanent_text_.length() : 0); |
407 NetworkActionPredictor* network_action_predictor = | 407 NetworkActionPredictor* network_action_predictor = |
408 NetworkActionPredictorFactory::GetForProfile(profile_); | 408 NetworkActionPredictorFactory::GetForProfile(profile_); |
409 if (network_action_predictor) | 409 if (network_action_predictor) |
410 network_action_predictor->ClearTransitionalMatches(); | 410 network_action_predictor->ClearTransitionalMatches(); |
411 } | 411 } |
412 | 412 |
413 void AutocompleteEditModel::StartAutocomplete( | 413 void AutocompleteEditModel::StartAutocomplete( |
414 bool has_selected_text, | 414 bool has_selected_text, |
415 bool prevent_inline_autocomplete) const { | 415 bool prevent_inline_autocomplete) const { |
| 416 ClearPopupKeywordMode(); |
| 417 |
416 bool keyword_is_selected = KeywordIsSelected(); | 418 bool keyword_is_selected = KeywordIsSelected(); |
417 popup_->SetHoveredLine(AutocompletePopupModel::kNoMatch); | 419 popup_->SetHoveredLine(AutocompletePopupModel::kNoMatch); |
418 // We don't explicitly clear AutocompletePopupModel::manually_selected_match, | 420 // We don't explicitly clear AutocompletePopupModel::manually_selected_match, |
419 // as Start ends up invoking AutocompletePopupModel::OnResultChanged which | 421 // as Start ends up invoking AutocompletePopupModel::OnResultChanged which |
420 // clears it. | 422 // clears it. |
421 autocomplete_controller_->Start( | 423 autocomplete_controller_->Start( |
422 user_text_, GetDesiredTLD(), | 424 user_text_, GetDesiredTLD(), |
423 prevent_inline_autocomplete || just_deleted_text_ || | 425 prevent_inline_autocomplete || just_deleted_text_ || |
424 (has_selected_text && inline_autocomplete_text_.empty()) || | 426 (has_selected_text && inline_autocomplete_text_.empty()) || |
425 (paste_state_ != NONE), keyword_is_selected, | 427 (paste_state_ != NONE), keyword_is_selected, |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
603 | 605 |
604 InstantController* instant = controller_->GetInstant(); | 606 InstantController* instant = controller_->GetInstant(); |
605 if (instant && !popup_->IsOpen()) | 607 if (instant && !popup_->IsOpen()) |
606 instant->DestroyPreviewContents(); | 608 instant->DestroyPreviewContents(); |
607 in_revert_ = false; | 609 in_revert_ = false; |
608 } | 610 } |
609 | 611 |
610 bool AutocompleteEditModel::AcceptKeyword() { | 612 bool AutocompleteEditModel::AcceptKeyword() { |
611 DCHECK(is_keyword_hint_ && !keyword_.empty()); | 613 DCHECK(is_keyword_hint_ && !keyword_.empty()); |
612 | 614 |
613 view_->OnBeforePossibleChange(); | 615 autocomplete_controller_->Stop(false); |
614 view_->SetWindowTextAndCaretPos(string16(), 0); | |
615 is_keyword_hint_ = false; | 616 is_keyword_hint_ = false; |
616 view_->OnAfterPossibleChange(); | 617 |
617 just_deleted_text_ = false; // OnAfterPossibleChange() erroneously sets this | 618 if (popup_->IsOpen()) |
618 // since the edit contents have disappeared. It | 619 popup_->SetSelectedLineState(AutocompletePopupModel::KEYWORD); |
619 // doesn't really matter, but we clear it to be | 620 else |
620 // consistent. | 621 StartAutocomplete(false, true); |
| 622 |
| 623 string16 display_text = autocomplete_controller_->keyword_provider()-> |
| 624 SplitReplacementStringFromInput(user_text_, true); |
| 625 view_->SetUserText(string16(), display_text, false); |
| 626 |
621 content::RecordAction(UserMetricsAction("AcceptedKeywordHint")); | 627 content::RecordAction(UserMetricsAction("AcceptedKeywordHint")); |
622 return true; | 628 return true; |
623 } | 629 } |
624 | 630 |
625 void AutocompleteEditModel::ClearKeyword(const string16& visible_text) { | 631 void AutocompleteEditModel::ClearKeyword(const string16& visible_text) { |
626 view_->OnBeforePossibleChange(); | 632 autocomplete_controller_->Stop(false); |
| 633 ClearPopupKeywordMode(); |
| 634 |
627 const string16 window_text(keyword_ + visible_text); | 635 const string16 window_text(keyword_ + visible_text); |
628 view_->SetWindowTextAndCaretPos(window_text.c_str(), keyword_.length()); | 636 |
629 keyword_.clear(); | 637 // Only reset the result if the edit text has changed since the |
630 is_keyword_hint_ = false; | 638 // keyword was accepted, or if the popup is closed. |
631 view_->OnAfterPossibleChange(); | 639 if (just_deleted_text_ || !visible_text.empty() || !popup_->IsOpen()) { |
632 just_deleted_text_ = true; // OnAfterPossibleChange() fails to clear this | 640 view_->OnBeforePossibleChange(); |
633 // since the edit contents have actually grown | 641 view_->SetWindowTextAndCaretPos(window_text.c_str(), keyword_.length()); |
634 // longer. | 642 keyword_.clear(); |
| 643 is_keyword_hint_ = false; |
| 644 view_->OnAfterPossibleChange(); |
| 645 just_deleted_text_ = true; // OnAfterPossibleChange() fails to clear this |
| 646 // since the edit contents have actually grown |
| 647 // longer. |
| 648 } else { |
| 649 view_->SetUserText(window_text, window_text, false); |
| 650 is_keyword_hint_ = true; |
| 651 OnChanged(); |
| 652 } |
635 } | 653 } |
636 | 654 |
637 const AutocompleteResult& AutocompleteEditModel::result() const { | 655 const AutocompleteResult& AutocompleteEditModel::result() const { |
638 return autocomplete_controller_->result(); | 656 return autocomplete_controller_->result(); |
639 } | 657 } |
640 | 658 |
641 void AutocompleteEditModel::OnSetFocus(bool control_down) { | 659 void AutocompleteEditModel::OnSetFocus(bool control_down) { |
642 has_focus_ = true; | 660 has_focus_ = true; |
643 control_key_state_ = control_down ? DOWN_WITHOUT_CHANGE : UP; | 661 control_key_state_ = control_down ? DOWN_WITHOUT_CHANGE : UP; |
644 | 662 |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
887 match->fill_into_edit.substr(match->inline_autocomplete_offset); | 905 match->fill_into_edit.substr(match->inline_autocomplete_offset); |
888 } | 906 } |
889 | 907 |
890 if (!prerender::IsOmniboxEnabled(profile_)) | 908 if (!prerender::IsOmniboxEnabled(profile_)) |
891 DoPreconnect(*match); | 909 DoPreconnect(*match); |
892 | 910 |
893 // We could prefetch the alternate nav URL, if any, but because there | 911 // We could prefetch the alternate nav URL, if any, but because there |
894 // can be many of these as a user types an initial series of characters, | 912 // can be many of these as a user types an initial series of characters, |
895 // the OS DNS cache could suffer eviction problems for minimal gain. | 913 // the OS DNS cache could suffer eviction problems for minimal gain. |
896 | 914 |
897 is_keyword_hint = popup_->GetKeywordForMatch(*match, &keyword); | 915 is_keyword_hint = match->GetKeyword(&keyword); |
898 } | 916 } |
| 917 |
899 popup_->OnResultChanged(); | 918 popup_->OnResultChanged(); |
900 OnPopupDataChanged(inline_autocomplete_text, NULL, keyword, | 919 OnPopupDataChanged(inline_autocomplete_text, NULL, keyword, |
901 is_keyword_hint); | 920 is_keyword_hint); |
902 } else { | 921 } else { |
903 popup_->OnResultChanged(); | 922 popup_->OnResultChanged(); |
904 } | 923 } |
905 | 924 |
906 if (popup_->IsOpen()) { | 925 if (popup_->IsOpen()) { |
907 PopupBoundsChangedTo(popup_->view()->GetTargetBounds()); | 926 PopupBoundsChangedTo(popup_->view()->GetTargetBounds()); |
908 } else if (was_open) { | 927 } else if (was_open) { |
(...skipping 12 matching lines...) Expand all Loading... |
921 void AutocompleteEditModel::InternalSetUserText(const string16& text) { | 940 void AutocompleteEditModel::InternalSetUserText(const string16& text) { |
922 user_text_ = text; | 941 user_text_ = text; |
923 just_deleted_text_ = false; | 942 just_deleted_text_ = false; |
924 inline_autocomplete_text_.clear(); | 943 inline_autocomplete_text_.clear(); |
925 } | 944 } |
926 | 945 |
927 bool AutocompleteEditModel::KeywordIsSelected() const { | 946 bool AutocompleteEditModel::KeywordIsSelected() const { |
928 return !is_keyword_hint_ && !keyword_.empty(); | 947 return !is_keyword_hint_ && !keyword_.empty(); |
929 } | 948 } |
930 | 949 |
| 950 void AutocompleteEditModel::ClearPopupKeywordMode() const { |
| 951 if (popup_->IsOpen() && |
| 952 popup_->selected_line_state() == AutocompletePopupModel::KEYWORD) |
| 953 popup_->SetSelectedLineState(AutocompletePopupModel::NORMAL); |
| 954 } |
| 955 |
931 string16 AutocompleteEditModel::DisplayTextFromUserText( | 956 string16 AutocompleteEditModel::DisplayTextFromUserText( |
932 const string16& text) const { | 957 const string16& text) const { |
933 return KeywordIsSelected() ? | 958 return KeywordIsSelected() ? |
934 KeywordProvider::SplitReplacementStringFromInput(text, false) : text; | 959 KeywordProvider::SplitReplacementStringFromInput(text, false) : text; |
935 } | 960 } |
936 | 961 |
937 string16 AutocompleteEditModel::UserTextFromDisplayText( | 962 string16 AutocompleteEditModel::UserTextFromDisplayText( |
938 const string16& text) const { | 963 const string16& text) const { |
939 return KeywordIsSelected() ? (keyword_ + char16(' ') + text) : text; | 964 return KeywordIsSelected() ? (keyword_ + char16(' ') + text) : text; |
940 } | 965 } |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1020 old_user_text.length() - caret_position + 1)) { | 1045 old_user_text.length() - caret_position + 1)) { |
1021 return false; | 1046 return false; |
1022 } | 1047 } |
1023 | 1048 |
1024 // Then check if the text before the inserted space matches a keyword. | 1049 // Then check if the text before the inserted space matches a keyword. |
1025 string16 keyword; | 1050 string16 keyword; |
1026 TrimWhitespace(new_user_text.substr(0, caret_position - 1), | 1051 TrimWhitespace(new_user_text.substr(0, caret_position - 1), |
1027 TRIM_LEADING, &keyword); | 1052 TRIM_LEADING, &keyword); |
1028 | 1053 |
1029 // Only allow exact keyword match if |keyword| represents a keyword hint. | 1054 // Only allow exact keyword match if |keyword| represents a keyword hint. |
1030 return keyword.length() && popup_->GetKeywordForText(keyword, &keyword); | 1055 return keyword.length() && |
| 1056 !autocomplete_controller_->keyword_provider()-> |
| 1057 GetKeywordForText(keyword).empty(); |
1031 } | 1058 } |
1032 | 1059 |
1033 bool AutocompleteEditModel::DoInstant(const AutocompleteMatch& match, | 1060 bool AutocompleteEditModel::DoInstant(const AutocompleteMatch& match, |
1034 string16* suggested_text) { | 1061 string16* suggested_text) { |
1035 DCHECK(suggested_text); | 1062 DCHECK(suggested_text); |
1036 | 1063 |
1037 if (in_revert_) | 1064 if (in_revert_) |
1038 return false; | 1065 return false; |
1039 | 1066 |
1040 InstantController* instant = controller_->GetInstant(); | 1067 InstantController* instant = controller_->GetInstant(); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1096 // static | 1123 // static |
1097 bool AutocompleteEditModel::IsSpaceCharForAcceptingKeyword(wchar_t c) { | 1124 bool AutocompleteEditModel::IsSpaceCharForAcceptingKeyword(wchar_t c) { |
1098 switch (c) { | 1125 switch (c) { |
1099 case 0x0020: // Space | 1126 case 0x0020: // Space |
1100 case 0x3000: // Ideographic Space | 1127 case 0x3000: // Ideographic Space |
1101 return true; | 1128 return true; |
1102 default: | 1129 default: |
1103 return false; | 1130 return false; |
1104 } | 1131 } |
1105 } | 1132 } |
OLD | NEW |