OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
390 keyword_.clear(); | 390 keyword_.clear(); |
391 is_keyword_hint_ = false; | 391 is_keyword_hint_ = false; |
392 has_temporary_text_ = false; | 392 has_temporary_text_ = false; |
393 view_->SetWindowTextAndCaretPos(permanent_text_, | 393 view_->SetWindowTextAndCaretPos(permanent_text_, |
394 has_focus_ ? permanent_text_.length() : 0); | 394 has_focus_ ? permanent_text_.length() : 0); |
395 } | 395 } |
396 | 396 |
397 void AutocompleteEditModel::StartAutocomplete( | 397 void AutocompleteEditModel::StartAutocomplete( |
398 bool has_selected_text, | 398 bool has_selected_text, |
399 bool prevent_inline_autocomplete) const { | 399 bool prevent_inline_autocomplete) const { |
| 400 ClearPopupKeywordMode(); |
| 401 |
400 bool keyword_is_selected = KeywordIsSelected(); | 402 bool keyword_is_selected = KeywordIsSelected(); |
401 popup_->SetHoveredLine(AutocompletePopupModel::kNoMatch); | 403 popup_->SetHoveredLine(AutocompletePopupModel::kNoMatch); |
402 // We don't explicitly clear AutocompletePopupModel::manually_selected_match, | 404 // We don't explicitly clear AutocompletePopupModel::manually_selected_match, |
403 // as Start ends up invoking AutocompletePopupModel::OnResultChanged which | 405 // as Start ends up invoking AutocompletePopupModel::OnResultChanged which |
404 // clears it. | 406 // clears it. |
405 autocomplete_controller_->Start( | 407 autocomplete_controller_->Start( |
406 user_text_, GetDesiredTLD(), | 408 user_text_, GetDesiredTLD(), |
407 prevent_inline_autocomplete || just_deleted_text_ || | 409 prevent_inline_autocomplete || just_deleted_text_ || |
408 (has_selected_text && inline_autocomplete_text_.empty()) || | 410 (has_selected_text && inline_autocomplete_text_.empty()) || |
409 (paste_state_ != NONE), keyword_is_selected, | 411 (paste_state_ != NONE), keyword_is_selected, |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
553 | 555 |
554 InstantController* instant = controller_->GetInstant(); | 556 InstantController* instant = controller_->GetInstant(); |
555 if (instant && !popup_->IsOpen()) | 557 if (instant && !popup_->IsOpen()) |
556 instant->DestroyPreviewContents(); | 558 instant->DestroyPreviewContents(); |
557 in_revert_ = false; | 559 in_revert_ = false; |
558 } | 560 } |
559 | 561 |
560 bool AutocompleteEditModel::AcceptKeyword() { | 562 bool AutocompleteEditModel::AcceptKeyword() { |
561 DCHECK(is_keyword_hint_ && !keyword_.empty()); | 563 DCHECK(is_keyword_hint_ && !keyword_.empty()); |
562 | 564 |
563 view_->OnBeforePossibleChange(); | 565 autocomplete_controller_->Stop(false); |
564 view_->SetWindowTextAndCaretPos(string16(), 0); | |
565 is_keyword_hint_ = false; | 566 is_keyword_hint_ = false; |
566 view_->OnAfterPossibleChange(); | 567 |
567 just_deleted_text_ = false; // OnAfterPossibleChange() erroneously sets this | 568 if (popup_->IsOpen()) |
568 // since the edit contents have disappeared. It | 569 popup_->SetSelectedMatch(AutocompletePopupModel::KEYWORD); |
569 // doesn't really matter, but we clear it to be | 570 |
570 // consistent. | 571 view_->SetUserText(string16(), string16(), false); |
| 572 |
571 UserMetrics::RecordAction(UserMetricsAction("AcceptedKeywordHint")); | 573 UserMetrics::RecordAction(UserMetricsAction("AcceptedKeywordHint")); |
572 return true; | 574 return true; |
573 } | 575 } |
574 | 576 |
575 void AutocompleteEditModel::ClearKeyword(const string16& visible_text) { | 577 void AutocompleteEditModel::ClearKeyword(const string16& visible_text) { |
576 view_->OnBeforePossibleChange(); | 578 autocomplete_controller_->Stop(false); |
| 579 ClearPopupKeywordMode(); |
| 580 |
577 const string16 window_text(keyword_ + visible_text); | 581 const string16 window_text(keyword_ + visible_text); |
578 view_->SetWindowTextAndCaretPos(window_text.c_str(), keyword_.length()); | 582 |
579 keyword_.clear(); | 583 // Only reset the result if the edit text has changed since the |
580 is_keyword_hint_ = false; | 584 // keyword was accepted. |
581 view_->OnAfterPossibleChange(); | 585 if (just_deleted_text_) { |
582 just_deleted_text_ = true; // OnAfterPossibleChange() fails to clear this | 586 view_->OnBeforePossibleChange(); |
583 // since the edit contents have actually grown | 587 view_->SetWindowTextAndCaretPos(window_text.c_str(), keyword_.length()); |
584 // longer. | 588 keyword_.clear(); |
| 589 is_keyword_hint_ = false; |
| 590 view_->OnAfterPossibleChange(); |
| 591 just_deleted_text_ = true; // OnAfterPossibleChange() fails to clear this |
| 592 // since the edit contents have actually grown |
| 593 // longer. |
| 594 } else { |
| 595 view_->SetUserText(window_text, window_text, false); |
| 596 |
| 597 is_keyword_hint_ = visible_text.empty(); |
| 598 if (!is_keyword_hint_) |
| 599 keyword_.clear(); |
| 600 |
| 601 OnChanged(); |
| 602 } |
585 } | 603 } |
586 | 604 |
587 const AutocompleteResult& AutocompleteEditModel::result() const { | 605 const AutocompleteResult& AutocompleteEditModel::result() const { |
588 return autocomplete_controller_->result(); | 606 return autocomplete_controller_->result(); |
589 } | 607 } |
590 | 608 |
591 void AutocompleteEditModel::OnSetFocus(bool control_down) { | 609 void AutocompleteEditModel::OnSetFocus(bool control_down) { |
592 has_focus_ = true; | 610 has_focus_ = true; |
593 control_key_state_ = control_down ? DOWN_WITHOUT_CHANGE : UP; | 611 control_key_state_ = control_down ? DOWN_WITHOUT_CHANGE : UP; |
594 | 612 |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
859 if (!match->destination_url.SchemeIs(chrome::kExtensionScheme)) { | 877 if (!match->destination_url.SchemeIs(chrome::kExtensionScheme)) { |
860 // Warm up DNS Prefetch cache, or preconnect to a search service. | 878 // Warm up DNS Prefetch cache, or preconnect to a search service. |
861 chrome_browser_net::AnticipateOmniboxUrl(match->destination_url, | 879 chrome_browser_net::AnticipateOmniboxUrl(match->destination_url, |
862 IsPreconnectable(match->type)); | 880 IsPreconnectable(match->type)); |
863 } | 881 } |
864 | 882 |
865 // We could prefetch the alternate nav URL, if any, but because there | 883 // We could prefetch the alternate nav URL, if any, but because there |
866 // can be many of these as a user types an initial series of characters, | 884 // can be many of these as a user types an initial series of characters, |
867 // the OS DNS cache could suffer eviction problems for minimal gain. | 885 // the OS DNS cache could suffer eviction problems for minimal gain. |
868 | 886 |
869 is_keyword_hint = popup_->GetKeywordForMatch(*match, &keyword); | 887 keyword = match->keyword; |
| 888 is_keyword_hint = match->associated_keyword.get() != NULL; |
| 889 if (is_keyword_hint) |
| 890 keyword = match->associated_keyword->keyword; |
870 } | 891 } |
| 892 |
871 popup_->OnResultChanged(); | 893 popup_->OnResultChanged(); |
872 OnPopupDataChanged(inline_autocomplete_text, NULL, keyword, | 894 OnPopupDataChanged(inline_autocomplete_text, NULL, keyword, |
873 is_keyword_hint); | 895 is_keyword_hint); |
874 } else { | 896 } else { |
875 popup_->OnResultChanged(); | 897 popup_->OnResultChanged(); |
876 } | 898 } |
877 | 899 |
878 if (popup_->IsOpen()) { | 900 if (popup_->IsOpen()) { |
879 PopupBoundsChangedTo(popup_->view()->GetTargetBounds()); | 901 PopupBoundsChangedTo(popup_->view()->GetTargetBounds()); |
880 } else if (was_open) { | 902 } else if (was_open) { |
(...skipping 12 matching lines...) Expand all Loading... |
893 void AutocompleteEditModel::InternalSetUserText(const string16& text) { | 915 void AutocompleteEditModel::InternalSetUserText(const string16& text) { |
894 user_text_ = text; | 916 user_text_ = text; |
895 just_deleted_text_ = false; | 917 just_deleted_text_ = false; |
896 inline_autocomplete_text_.clear(); | 918 inline_autocomplete_text_.clear(); |
897 } | 919 } |
898 | 920 |
899 bool AutocompleteEditModel::KeywordIsSelected() const { | 921 bool AutocompleteEditModel::KeywordIsSelected() const { |
900 return !is_keyword_hint_ && !keyword_.empty(); | 922 return !is_keyword_hint_ && !keyword_.empty(); |
901 } | 923 } |
902 | 924 |
| 925 void AutocompleteEditModel::ClearPopupKeywordMode() const { |
| 926 if (popup_->IsOpen() && |
| 927 popup_->selected_match() == AutocompletePopupModel::KEYWORD) |
| 928 popup_->SetSelectedMatch(AutocompletePopupModel::NORMAL); |
| 929 } |
| 930 |
903 string16 AutocompleteEditModel::DisplayTextFromUserText( | 931 string16 AutocompleteEditModel::DisplayTextFromUserText( |
904 const string16& text) const { | 932 const string16& text) const { |
905 return KeywordIsSelected() ? | 933 return KeywordIsSelected() ? |
906 KeywordProvider::SplitReplacementStringFromInput(text, false) : text; | 934 KeywordProvider::SplitReplacementStringFromInput(text, false) : text; |
907 } | 935 } |
908 | 936 |
909 string16 AutocompleteEditModel::UserTextFromDisplayText( | 937 string16 AutocompleteEditModel::UserTextFromDisplayText( |
910 const string16& text) const { | 938 const string16& text) const { |
911 return KeywordIsSelected() ? (keyword_ + char16(' ') + text) : text; | 939 return KeywordIsSelected() ? (keyword_ + char16(' ') + text) : text; |
912 } | 940 } |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1004 old_user_text.length() - caret_position + 1)) { | 1032 old_user_text.length() - caret_position + 1)) { |
1005 return false; | 1033 return false; |
1006 } | 1034 } |
1007 | 1035 |
1008 // Then check if the text before the inserted space matches a keyword. | 1036 // Then check if the text before the inserted space matches a keyword. |
1009 string16 keyword; | 1037 string16 keyword; |
1010 TrimWhitespace(new_user_text.substr(0, caret_position - 1), | 1038 TrimWhitespace(new_user_text.substr(0, caret_position - 1), |
1011 TRIM_LEADING, &keyword); | 1039 TRIM_LEADING, &keyword); |
1012 | 1040 |
1013 // Only allow exact keyword match if |keyword| represents a keyword hint. | 1041 // Only allow exact keyword match if |keyword| represents a keyword hint. |
1014 return keyword.length() && popup_->GetKeywordForText(keyword, &keyword); | 1042 return keyword.length() && |
| 1043 !autocomplete_controller_->keyword_provider()-> |
| 1044 GetKeywordForText(keyword).empty(); |
1015 } | 1045 } |
1016 | 1046 |
1017 // static | 1047 // static |
1018 bool AutocompleteEditModel::IsSpaceCharForAcceptingKeyword(wchar_t c) { | 1048 bool AutocompleteEditModel::IsSpaceCharForAcceptingKeyword(wchar_t c) { |
1019 switch (c) { | 1049 switch (c) { |
1020 case 0x0020: // Space | 1050 case 0x0020: // Space |
1021 case 0x3000: // Ideographic Space | 1051 case 0x3000: // Ideographic Space |
1022 return true; | 1052 return true; |
1023 default: | 1053 default: |
1024 return false; | 1054 return false; |
1025 } | 1055 } |
1026 } | 1056 } |
OLD | NEW |