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 627 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
638 // to update the popup if it's open, since the desired_tld will have changed. | 638 // to update the popup if it's open, since the desired_tld will have changed. |
639 if ((text_differs || selection_differs) && | 639 if ((text_differs || selection_differs) && |
640 (control_key_state_ == DOWN_WITHOUT_CHANGE)) { | 640 (control_key_state_ == DOWN_WITHOUT_CHANGE)) { |
641 control_key_state_ = DOWN_WITH_CHANGE; | 641 control_key_state_ = DOWN_WITH_CHANGE; |
642 if (!text_differs && !popup_->IsOpen()) | 642 if (!text_differs && !popup_->IsOpen()) |
643 return false; // Don't open the popup for no reason. | 643 return false; // Don't open the popup for no reason. |
644 } else if (!user_text_changed) { | 644 } else if (!user_text_changed) { |
645 return false; | 645 return false; |
646 } | 646 } |
647 | 647 |
| 648 const std::wstring old_user_text = user_text_; |
648 // If the user text has not changed, we do not want to change the model's | 649 // If the user text has not changed, we do not want to change the model's |
649 // state associated with the text. Otherwise, we can get surprising behavior | 650 // state associated with the text. Otherwise, we can get surprising behavior |
650 // where the autocompleted text unexpectedly reappears, e.g. crbug.com/55983 | 651 // where the autocompleted text unexpectedly reappears, e.g. crbug.com/55983 |
651 if (user_text_changed) { | 652 if (user_text_changed) { |
652 const std::wstring new_user_text = UserTextFromDisplayText(new_text); | 653 InternalSetUserText(UserTextFromDisplayText(new_text)); |
653 | |
654 // Try to accept the current keyword if the user only typed a space at the | |
655 // end of content. Model's state and popup will be updated when the keyword | |
656 // is accepted. So we just need to return false here. | |
657 if (allow_keyword_ui_change && !selection_differs && | |
658 MaybeAcceptKeywordBySpace(new_user_text)) | |
659 return false; | |
660 | |
661 InternalSetUserText(new_user_text); | |
662 has_temporary_text_ = false; | 654 has_temporary_text_ = false; |
663 | 655 |
664 // Track when the user has deleted text so we won't allow inline | 656 // Track when the user has deleted text so we won't allow inline |
665 // autocomplete. | 657 // autocomplete. |
666 just_deleted_text_ = just_deleted_text; | 658 just_deleted_text_ = just_deleted_text; |
667 } | 659 } |
668 | 660 |
669 view_->UpdatePopup(); | 661 view_->UpdatePopup(); |
| 662 |
| 663 // Change to keyword mode if the user has typed a keyword name and is now |
| 664 // pressing space after the name. Accepting the keyword will update our |
| 665 // state, so in that case there's no need to also return true here. |
| 666 if (text_differs && allow_keyword_ui_change && !just_deleted_text && |
| 667 MaybeAcceptKeywordBySpace(old_user_text, user_text_)) |
| 668 return false; |
| 669 |
670 return true; | 670 return true; |
671 } | 671 } |
672 | 672 |
673 void AutocompleteEditModel::PopupBoundsChangedTo(const gfx::Rect& bounds) { | 673 void AutocompleteEditModel::PopupBoundsChangedTo(const gfx::Rect& bounds) { |
674 controller_->OnPopupBoundsChanged(bounds); | 674 controller_->OnPopupBoundsChanged(bounds); |
675 } | 675 } |
676 | 676 |
677 void AutocompleteEditModel::OnPopupClosed() { | 677 void AutocompleteEditModel::OnPopupClosed() { |
678 // Accepts the temporary text as the user text, because it makes little | 678 // Accepts the temporary text as the user text, because it makes little |
679 // sense to have temporary text when the popup is closed. | 679 // sense to have temporary text when the popup is closed. |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
775 const AutocompleteInput::Type type = AutocompleteInput::Parse( | 775 const AutocompleteInput::Type type = AutocompleteInput::Parse( |
776 UserTextFromDisplayText(text), std::wstring(), NULL, NULL, &parsed_url); | 776 UserTextFromDisplayText(text), std::wstring(), NULL, NULL, &parsed_url); |
777 if (type != AutocompleteInput::URL) | 777 if (type != AutocompleteInput::URL) |
778 return false; | 778 return false; |
779 | 779 |
780 *url = parsed_url; | 780 *url = parsed_url; |
781 return true; | 781 return true; |
782 } | 782 } |
783 | 783 |
784 bool AutocompleteEditModel::MaybeAcceptKeywordBySpace( | 784 bool AutocompleteEditModel::MaybeAcceptKeywordBySpace( |
| 785 const std::wstring& old_user_text, |
785 const std::wstring& new_user_text) { | 786 const std::wstring& new_user_text) { |
786 return (paste_state_ == NONE) && is_keyword_hint_ && !keyword_.empty() && | 787 return (paste_state_ == NONE) && is_keyword_hint_ && !keyword_.empty() && |
787 inline_autocomplete_text_.empty() && !user_text_.empty() && | 788 inline_autocomplete_text_.empty() && new_user_text.length() >= 2 && |
788 (new_user_text.length() == user_text_.length() + 1) && | 789 IsSpaceCharForAcceptingKeyword(*new_user_text.rbegin()) && |
789 !new_user_text.compare(0, user_text_.length(), user_text_) && | 790 !IsWhitespace(*(new_user_text.rbegin() + 1)) && |
790 IsSpaceCharForAcceptingKeyword(new_user_text[user_text_.length()]) && | 791 (old_user_text.length() + 1 >= new_user_text.length()) && |
791 !IsWhitespace(user_text_[user_text_.length() - 1]) && | 792 !new_user_text.compare(0, new_user_text.length() - 1, old_user_text, |
| 793 0, new_user_text.length() - 1) && |
792 AcceptKeyword(); | 794 AcceptKeyword(); |
793 } | 795 } |
794 | 796 |
795 // static | 797 // static |
796 bool AutocompleteEditModel::IsSpaceCharForAcceptingKeyword(wchar_t c) { | 798 bool AutocompleteEditModel::IsSpaceCharForAcceptingKeyword(wchar_t c) { |
797 switch (c) { | 799 switch (c) { |
798 case 0x0020: // Space | 800 case 0x0020: // Space |
799 case 0x3000: // Ideographic Space | 801 case 0x3000: // Ideographic Space |
800 return true; | 802 return true; |
801 default: | 803 default: |
802 return false; | 804 return false; |
803 } | 805 } |
804 } | 806 } |
OLD | NEW |