Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(109)

Side by Side Diff: chrome/browser/autocomplete/autocomplete_edit.cc

Issue 6340012: Fix a DCHECK failure in AutocompleteEditModel::OnPopupDataChanged() (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Update. Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 468 matching lines...) Expand 10 before | Expand all | Expand 10 after
479 has_focus_ = false; 479 has_focus_ = false;
480 control_key_state_ = UP; 480 control_key_state_ = UP;
481 paste_state_ = NONE; 481 paste_state_ = NONE;
482 } 482 }
483 483
484 bool AutocompleteEditModel::OnEscapeKeyPressed() { 484 bool AutocompleteEditModel::OnEscapeKeyPressed() {
485 if (has_temporary_text_) { 485 if (has_temporary_text_) {
486 AutocompleteMatch match; 486 AutocompleteMatch match;
487 popup_->InfoForCurrentSelection(&match, NULL); 487 popup_->InfoForCurrentSelection(&match, NULL);
488 if (match.destination_url != original_url_) { 488 if (match.destination_url != original_url_) {
489 // The user typed something, then selected a different item. Restore the 489 RevertTemporaryText(true);
490 // text they typed and change back to the default item.
491 // NOTE: This purposefully does not reset paste_state_.
492 just_deleted_text_ = false;
493 has_temporary_text_ = false;
494 popup_->ResetToDefaultMatch();
495 view_->OnRevertTemporaryText();
496 return true; 490 return true;
497 } 491 }
498 } 492 }
499 493
500 // If the user wasn't editing, but merely had focus in the edit, allow <esc> 494 // If the user wasn't editing, but merely had focus in the edit, allow <esc>
501 // to be processed as an accelerator, so it can still be used to stop a load. 495 // to be processed as an accelerator, so it can still be used to stop a load.
502 // When the permanent text isn't all selected we still fall through to the 496 // When the permanent text isn't all selected we still fall through to the
503 // SelectAll() call below so users can arrow around in the text and then hit 497 // SelectAll() call below so users can arrow around in the text and then hit
504 // <esc> to quickly replace all the text; this matches IE. 498 // <esc> to quickly replace all the text; this matches IE.
505 if (!user_input_in_progress_ && view_->IsSelectAll()) 499 if (!user_input_in_progress_ && view_->IsSelectAll())
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
592 // user's selection gets screwy; and if we don't update the popup, and the 586 // user's selection gets screwy; and if we don't update the popup, and the
593 // user reverts, then the selected item will be as if control is still 587 // user reverts, then the selected item will be as if control is still
594 // pressed, even though maybe it isn't any more. There is no obvious 588 // pressed, even though maybe it isn't any more. There is no obvious
595 // right answer here :( 589 // right answer here :(
596 } 590 }
597 view_->OnTemporaryTextMaybeChanged(DisplayTextFromUserText(text), 591 view_->OnTemporaryTextMaybeChanged(DisplayTextFromUserText(text),
598 save_original_selection); 592 save_original_selection);
599 return; 593 return;
600 } 594 }
601 595
602 // All cases that can result in |has_temporary_text_| being set should have 596 bool call_controller_onchanged = true;
603 // been handled by the conditional above.
604 DCHECK(!has_temporary_text_);
605
606 inline_autocomplete_text_ = text; 597 inline_autocomplete_text_ = text;
607 if (view_->OnInlineAutocompleteTextMaybeChanged( 598 if (view_->OnInlineAutocompleteTextMaybeChanged(
608 DisplayTextFromUserText(user_text_ + inline_autocomplete_text_), 599 DisplayTextFromUserText(user_text_ + inline_autocomplete_text_),
609 DisplayTextFromUserText(user_text_).length())) 600 DisplayTextFromUserText(user_text_).length()))
610 return; 601 call_controller_onchanged = false;
611 602
612 // All other code paths that return invoke OnChanged. We need to invoke 603 // If |has_temporary_text_| is true, then we previously had a manual selection
613 // OnChanged in case the destination url changed (as could happen when control 604 // but now don't (or |destination_for_temporary_text_change| would have been
614 // is toggled). 605 // non-NULL). This can happen when deleting the selected item in the popup.
615 controller_->OnChanged(); 606 // In this case, we've already reverted the popup to the default match, so we
607 // need to revert ourselves as well.
608 if (has_temporary_text_) {
609 RevertTemporaryText(false);
610 call_controller_onchanged = false;
611 }
612
613 // We need to invoke OnChanged in case the destination url changed (as could
614 // happen when control is toggled).
615 if (call_controller_onchanged)
616 controller_->OnChanged();
616 } 617 }
617 618
618 bool AutocompleteEditModel::OnAfterPossibleChange( 619 bool AutocompleteEditModel::OnAfterPossibleChange(
619 const string16& new_text, 620 const string16& new_text,
620 bool selection_differs, 621 bool selection_differs,
621 bool text_differs, 622 bool text_differs,
622 bool just_deleted_text, 623 bool just_deleted_text,
623 bool allow_keyword_ui_change) { 624 bool allow_keyword_ui_change) {
624 // Update the paste state as appropriate: if we're just finishing a paste 625 // Update the paste state as appropriate: if we're just finishing a paste
625 // that replaced all the text, preserve that information; otherwise, if we've 626 // that replaced all the text, preserve that information; otherwise, if we've
(...skipping 30 matching lines...) Expand all
656 // Track when the user has deleted text so we won't allow inline 657 // Track when the user has deleted text so we won't allow inline
657 // autocomplete. 658 // autocomplete.
658 just_deleted_text_ = just_deleted_text; 659 just_deleted_text_ = just_deleted_text;
659 } 660 }
660 661
661 view_->UpdatePopup(); 662 view_->UpdatePopup();
662 663
663 // Change to keyword mode if the user has typed a keyword name and is now 664 // 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 // 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 // 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 return !(text_differs && allow_keyword_ui_change && !just_deleted_text &&
667 MaybeAcceptKeywordBySpace(old_user_text, user_text_)) 668 MaybeAcceptKeywordBySpace(old_user_text, user_text_));
668 return false;
669
670 return true;
671 } 669 }
672 670
673 void AutocompleteEditModel::PopupBoundsChangedTo(const gfx::Rect& bounds) { 671 void AutocompleteEditModel::PopupBoundsChangedTo(const gfx::Rect& bounds) {
674 controller_->OnPopupBoundsChanged(bounds); 672 controller_->OnPopupBoundsChanged(bounds);
675 } 673 }
676 674
677 void AutocompleteEditModel::OnPopupClosed() { 675 void AutocompleteEditModel::OnPopupClosed() {
678 // Accepts the temporary text as the user text, because it makes little 676 // Accepts the temporary text as the user text, because it makes little
679 // sense to have temporary text when the popup is closed. 677 // sense to have temporary text when the popup is closed.
680 InternalSetUserText(UserTextFromDisplayText(view_->GetText())); 678 InternalSetUserText(UserTextFromDisplayText(view_->GetText()));
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
774 GURL parsed_url; 772 GURL parsed_url;
775 const AutocompleteInput::Type type = AutocompleteInput::Parse( 773 const AutocompleteInput::Type type = AutocompleteInput::Parse(
776 UserTextFromDisplayText(text), string16(), NULL, NULL, &parsed_url); 774 UserTextFromDisplayText(text), string16(), NULL, NULL, &parsed_url);
777 if (type != AutocompleteInput::URL) 775 if (type != AutocompleteInput::URL)
778 return false; 776 return false;
779 777
780 *url = parsed_url; 778 *url = parsed_url;
781 return true; 779 return true;
782 } 780 }
783 781
782 void AutocompleteEditModel::RevertTemporaryText(bool revert_popup) {
783 // The user typed something, then selected a different item. Restore the
784 // text they typed and change back to the default item.
785 // NOTE: This purposefully does not reset paste_state_.
786 just_deleted_text_ = false;
787 has_temporary_text_ = false;
788 if (revert_popup)
789 popup_->ResetToDefaultMatch();
790 view_->OnRevertTemporaryText();
791 }
792
784 bool AutocompleteEditModel::MaybeAcceptKeywordBySpace( 793 bool AutocompleteEditModel::MaybeAcceptKeywordBySpace(
785 const string16& old_user_text, 794 const string16& old_user_text,
786 const string16& new_user_text) { 795 const string16& new_user_text) {
787 return (paste_state_ == NONE) && is_keyword_hint_ && !keyword_.empty() && 796 return (paste_state_ == NONE) && is_keyword_hint_ && !keyword_.empty() &&
788 inline_autocomplete_text_.empty() && new_user_text.length() >= 2 && 797 inline_autocomplete_text_.empty() && new_user_text.length() >= 2 &&
789 IsSpaceCharForAcceptingKeyword(*new_user_text.rbegin()) && 798 IsSpaceCharForAcceptingKeyword(*new_user_text.rbegin()) &&
790 !IsWhitespace(*(new_user_text.rbegin() + 1)) && 799 !IsWhitespace(*(new_user_text.rbegin() + 1)) &&
791 (old_user_text.length() + 1 >= new_user_text.length()) && 800 (old_user_text.length() + 1 >= new_user_text.length()) &&
792 !new_user_text.compare(0, new_user_text.length() - 1, old_user_text, 801 !new_user_text.compare(0, new_user_text.length() - 1, old_user_text,
793 0, new_user_text.length() - 1) && 802 0, new_user_text.length() - 1) &&
794 AcceptKeyword(); 803 AcceptKeyword();
795 } 804 }
796 805
797 // static 806 // static
798 bool AutocompleteEditModel::IsSpaceCharForAcceptingKeyword(wchar_t c) { 807 bool AutocompleteEditModel::IsSpaceCharForAcceptingKeyword(wchar_t c) {
799 switch (c) { 808 switch (c) {
800 case 0x0020: // Space 809 case 0x0020: // Space
801 case 0x3000: // Ideographic Space 810 case 0x3000: // Ideographic Space
802 return true; 811 return true;
803 default: 812 default:
804 return false; 813 return false;
805 } 814 }
806 } 815 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698