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 <string> | 7 #include <string> |
8 | 8 |
9 #include "base/auto_reset.h" | 9 #include "base/auto_reset.h" |
10 #include "base/format_macros.h" | 10 #include "base/format_macros.h" |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
113 OmniboxEditModel::State::~State() { | 113 OmniboxEditModel::State::~State() { |
114 } | 114 } |
115 | 115 |
116 /////////////////////////////////////////////////////////////////////////////// | 116 /////////////////////////////////////////////////////////////////////////////// |
117 // OmniboxEditModel | 117 // OmniboxEditModel |
118 | 118 |
119 OmniboxEditModel::OmniboxEditModel(OmniboxView* view, | 119 OmniboxEditModel::OmniboxEditModel(OmniboxView* view, |
120 OmniboxEditController* controller, | 120 OmniboxEditController* controller, |
121 Profile* profile) | 121 Profile* profile) |
122 : view_(view), | 122 : view_(view), |
123 popup_(NULL), | |
124 controller_(controller), | 123 controller_(controller), |
125 focus_state_(OMNIBOX_FOCUS_NONE), | 124 focus_state_(OMNIBOX_FOCUS_NONE), |
126 user_input_in_progress_(false), | 125 user_input_in_progress_(false), |
127 just_deleted_text_(false), | 126 just_deleted_text_(false), |
128 has_temporary_text_(false), | 127 has_temporary_text_(false), |
129 is_temporary_text_set_by_instant_(false), | 128 is_temporary_text_set_by_instant_(false), |
130 is_instant_temporary_text_a_search_query_(false), | 129 is_instant_temporary_text_a_search_query_(false), |
131 paste_state_(NONE), | 130 paste_state_(NONE), |
132 control_key_state_(UP), | 131 control_key_state_(UP), |
133 is_keyword_hint_(false), | 132 is_keyword_hint_(false), |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
226 | 225 |
227 void OmniboxEditModel::FinalizeInstantQuery(const string16& input_text, | 226 void OmniboxEditModel::FinalizeInstantQuery(const string16& input_text, |
228 const InstantSuggestion& suggestion, | 227 const InstantSuggestion& suggestion, |
229 bool skip_inline_autocomplete) { | 228 bool skip_inline_autocomplete) { |
230 if (skip_inline_autocomplete) { | 229 if (skip_inline_autocomplete) { |
231 const string16 final_text = input_text + suggestion.text; | 230 const string16 final_text = input_text + suggestion.text; |
232 view_->OnBeforePossibleChange(); | 231 view_->OnBeforePossibleChange(); |
233 view_->SetWindowTextAndCaretPos(final_text, final_text.length(), false, | 232 view_->SetWindowTextAndCaretPos(final_text, final_text.length(), false, |
234 false); | 233 false); |
235 view_->OnAfterPossibleChange(); | 234 view_->OnAfterPossibleChange(); |
236 } else if (popup_->IsOpen()) { | 235 } else if (popup_model()->IsOpen()) { |
237 SearchProvider* search_provider = | 236 SearchProvider* search_provider = |
238 autocomplete_controller()->search_provider(); | 237 autocomplete_controller()->search_provider(); |
239 // There may be no providers during testing; guard against that. | 238 // There may be no providers during testing; guard against that. |
240 if (search_provider) | 239 if (search_provider) |
241 search_provider->FinalizeInstantQuery(input_text, suggestion); | 240 search_provider->FinalizeInstantQuery(input_text, suggestion); |
242 } | 241 } |
243 } | 242 } |
244 | 243 |
245 void OmniboxEditModel::SetInstantSuggestion( | 244 void OmniboxEditModel::SetInstantSuggestion( |
246 const InstantSuggestion& suggestion) { | 245 const InstantSuggestion& suggestion) { |
247 switch (suggestion.behavior) { | 246 switch (suggestion.behavior) { |
248 case INSTANT_COMPLETE_NOW: | 247 case INSTANT_COMPLETE_NOW: |
249 view_->SetInstantSuggestion(string16()); | 248 view_->SetInstantSuggestion(string16()); |
250 if (!suggestion.text.empty()) | 249 if (!suggestion.text.empty()) |
251 FinalizeInstantQuery(view_->GetText(), suggestion, false); | 250 FinalizeInstantQuery(view_->GetText(), suggestion, false); |
252 break; | 251 break; |
253 | 252 |
254 case INSTANT_COMPLETE_NEVER: { | 253 case INSTANT_COMPLETE_NEVER: { |
255 DCHECK_EQ(INSTANT_SUGGESTION_SEARCH, suggestion.type); | 254 DCHECK_EQ(INSTANT_SUGGESTION_SEARCH, suggestion.type); |
256 view_->SetInstantSuggestion(suggestion.text); | 255 view_->SetInstantSuggestion(suggestion.text); |
257 autocomplete_controller()->search_provider()->ClearInstantSuggestion(); | 256 SearchProvider* search_provider = |
257 autocomplete_controller()->search_provider(); | |
258 if (search_provider) | |
259 search_provider->ClearInstantSuggestion(); | |
258 break; | 260 break; |
259 } | 261 } |
260 | 262 |
261 case INSTANT_COMPLETE_REPLACE: { | 263 case INSTANT_COMPLETE_REPLACE: { |
262 const bool save_original_selection = !has_temporary_text_; | 264 const bool save_original_selection = !has_temporary_text_; |
263 view_->SetInstantSuggestion(string16()); | 265 view_->SetInstantSuggestion(string16()); |
264 has_temporary_text_ = true; | 266 has_temporary_text_ = true; |
265 is_temporary_text_set_by_instant_ = true; | 267 is_temporary_text_set_by_instant_ = true; |
266 is_instant_temporary_text_a_search_query_ = | 268 is_instant_temporary_text_a_search_query_ = |
267 suggestion.type == INSTANT_SUGGESTION_SEARCH; | 269 suggestion.type == INSTANT_SUGGESTION_SEARCH; |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
335 // has been closed or on return from a sleep state. | 337 // has been closed or on return from a sleep state. |
336 // (http://crbug.com/105689) | 338 // (http://crbug.com/105689) |
337 if (!delegate_->CurrentPageExists()) | 339 if (!delegate_->CurrentPageExists()) |
338 break; | 340 break; |
339 // Ask for prerendering if the destination URL is different than the | 341 // Ask for prerendering if the destination URL is different than the |
340 // current URL. | 342 // current URL. |
341 if (current_match.destination_url != PermanentURL()) | 343 if (current_match.destination_url != PermanentURL()) |
342 delegate_->DoPrerender(current_match); | 344 delegate_->DoPrerender(current_match); |
343 break; | 345 break; |
344 case AutocompleteActionPredictor::ACTION_PRECONNECT: | 346 case AutocompleteActionPredictor::ACTION_PRECONNECT: |
345 DoPreconnect(current_match); | 347 omnibox_controller_->DoPreconnect(current_match); |
346 break; | 348 break; |
347 case AutocompleteActionPredictor::ACTION_NONE: | 349 case AutocompleteActionPredictor::ACTION_NONE: |
348 break; | 350 break; |
349 } | 351 } |
350 | 352 |
351 controller_->OnChanged(); | 353 controller_->OnChanged(); |
352 } | 354 } |
353 | 355 |
354 void OmniboxEditModel::GetDataForURLExport(GURL* url, | 356 void OmniboxEditModel::GetDataForURLExport(GURL* url, |
355 string16* title, | 357 string16* title, |
(...skipping 18 matching lines...) Expand all Loading... | |
374 #endif | 376 #endif |
375 | 377 |
376 // The value of input.prevent_inline_autocomplete() is determined by the | 378 // The value of input.prevent_inline_autocomplete() is determined by the |
377 // following conditions: | 379 // following conditions: |
378 // 1. If the caret is at the end of the text. | 380 // 1. If the caret is at the end of the text. |
379 // 2. If it's in IME composition mode. | 381 // 2. If it's in IME composition mode. |
380 // We send the caret position to Instant (so it can determine #1 itself), and | 382 // We send the caret position to Instant (so it can determine #1 itself), and |
381 // we use a separated widget for displaying the Instant suggest (so it doesn't | 383 // we use a separated widget for displaying the Instant suggest (so it doesn't |
382 // interfere with #2). So, we don't need to care about the value of | 384 // interfere with #2). So, we don't need to care about the value of |
383 // input.prevent_inline_autocomplete() here. | 385 // input.prevent_inline_autocomplete() here. |
384 return view_->DeleteAtEndPressed() || popup_->selected_line() != 0 || | 386 return view_->DeleteAtEndPressed() || popup_model()->selected_line() != 0 || |
385 just_deleted_text_; | 387 just_deleted_text_; |
386 } | 388 } |
387 | 389 |
388 bool OmniboxEditModel::CurrentTextIsURL() const { | 390 bool OmniboxEditModel::CurrentTextIsURL() const { |
389 if (view_->toolbar_model()->GetSearchTermsType() != | 391 if (view_->toolbar_model()->GetSearchTermsType() != |
390 ToolbarModel::NO_SEARCH_TERMS) | 392 ToolbarModel::NO_SEARCH_TERMS) |
391 return false; | 393 return false; |
392 | 394 |
393 // If current text is not composed of replaced search terms and | 395 // If current text is not composed of replaced search terms and |
394 // !user_input_in_progress_, then permanent text is showing and should be a | 396 // !user_input_in_progress_, then permanent text is showing and should be a |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
487 false, true); | 489 false, true); |
488 AutocompleteActionPredictor* action_predictor = | 490 AutocompleteActionPredictor* action_predictor = |
489 AutocompleteActionPredictorFactory::GetForProfile(profile_); | 491 AutocompleteActionPredictorFactory::GetForProfile(profile_); |
490 if (action_predictor) | 492 if (action_predictor) |
491 action_predictor->ClearTransitionalMatches(); | 493 action_predictor->ClearTransitionalMatches(); |
492 } | 494 } |
493 | 495 |
494 void OmniboxEditModel::StartAutocomplete( | 496 void OmniboxEditModel::StartAutocomplete( |
495 bool has_selected_text, | 497 bool has_selected_text, |
496 bool prevent_inline_autocomplete) const { | 498 bool prevent_inline_autocomplete) const { |
497 ClearPopupKeywordMode(); | 499 omnibox_controller_->ClearPopupKeywordMode(); |
498 | 500 |
499 bool keyword_is_selected = KeywordIsSelected(); | 501 bool keyword_is_selected = KeywordIsSelected(); |
500 popup_->SetHoveredLine(OmniboxPopupModel::kNoMatch); | 502 popup_model()->SetHoveredLine(OmniboxPopupModel::kNoMatch); |
501 | 503 |
502 size_t cursor_position; | 504 size_t cursor_position; |
503 if (inline_autocomplete_text_.empty()) { | 505 if (inline_autocomplete_text_.empty()) { |
504 // Cursor position is equivalent to the current selection's end. | 506 // Cursor position is equivalent to the current selection's end. |
505 size_t start; | 507 size_t start; |
506 view_->GetSelectionBounds(&start, &cursor_position); | 508 view_->GetSelectionBounds(&start, &cursor_position); |
507 // Adjust cursor position taking into account possible keyword in the user | 509 // Adjust cursor position taking into account possible keyword in the user |
508 // text. We rely on DisplayTextFromUserText() method which is consistent | 510 // text. We rely on DisplayTextFromUserText() method which is consistent |
509 // with keyword extraction done in KeywordProvider/SearchProvider. | 511 // with keyword extraction done in KeywordProvider/SearchProvider. |
510 const size_t cursor_offset = | 512 const size_t cursor_offset = |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
632 view_->OpenMatch(match, disposition, alternate_nav_url, | 634 view_->OpenMatch(match, disposition, alternate_nav_url, |
633 OmniboxPopupModel::kNoMatch); | 635 OmniboxPopupModel::kNoMatch); |
634 } | 636 } |
635 | 637 |
636 void OmniboxEditModel::OpenMatch(const AutocompleteMatch& match, | 638 void OmniboxEditModel::OpenMatch(const AutocompleteMatch& match, |
637 WindowOpenDisposition disposition, | 639 WindowOpenDisposition disposition, |
638 const GURL& alternate_nav_url, | 640 const GURL& alternate_nav_url, |
639 size_t index) { | 641 size_t index) { |
640 // We only care about cases where there is a selection (i.e. the popup is | 642 // We only care about cases where there is a selection (i.e. the popup is |
641 // open). | 643 // open). |
642 if (popup_->IsOpen()) { | 644 if (popup_model()->IsOpen()) { |
643 const base::TimeTicks& now(base::TimeTicks::Now()); | 645 const base::TimeTicks& now(base::TimeTicks::Now()); |
644 // TODO(sreeram): Handle is_temporary_text_set_by_instant_ correctly. | 646 // TODO(sreeram): Handle is_temporary_text_set_by_instant_ correctly. |
645 AutocompleteLog log( | 647 AutocompleteLog log( |
646 autocomplete_controller()->input().text(), | 648 autocomplete_controller()->input().text(), |
647 just_deleted_text_, | 649 just_deleted_text_, |
648 autocomplete_controller()->input().type(), | 650 autocomplete_controller()->input().type(), |
649 popup_->selected_line(), | 651 popup_model()->selected_line(), |
650 -1, // don't yet know tab ID; set later if appropriate | 652 -1, // don't yet know tab ID; set later if appropriate |
651 delegate_->CurrentPageExists() ? ClassifyPage(delegate_->GetURL()) : | 653 delegate_->CurrentPageExists() ? ClassifyPage(delegate_->GetURL()) : |
652 metrics::OmniboxEventProto_PageClassification_OTHER, | 654 metrics::OmniboxEventProto_PageClassification_OTHER, |
653 now - time_user_first_modified_omnibox_, | 655 now - time_user_first_modified_omnibox_, |
654 string16::npos, // completed_length; possibly set later | 656 string16::npos, // completed_length; possibly set later |
655 now - autocomplete_controller()->last_time_default_match_changed(), | 657 now - autocomplete_controller()->last_time_default_match_changed(), |
656 result()); | 658 result()); |
657 DCHECK(user_input_in_progress_ || | 659 DCHECK(user_input_in_progress_ || |
658 match.provider->type() == AutocompleteProvider::TYPE_ZERO_SUGGEST) | 660 match.provider->type() == AutocompleteProvider::TYPE_ZERO_SUGGEST) |
659 << "We didn't get here through the expected series of calls. " | 661 << "We didn't get here through the expected series of calls. " |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
758 if (match.starred) | 760 if (match.starred) |
759 bookmark_utils::RecordBookmarkLaunch(bookmark_utils::LAUNCH_OMNIBOX); | 761 bookmark_utils::RecordBookmarkLaunch(bookmark_utils::LAUNCH_OMNIBOX); |
760 } | 762 } |
761 | 763 |
762 bool OmniboxEditModel::AcceptKeyword(EnteredKeywordModeMethod entered_method) { | 764 bool OmniboxEditModel::AcceptKeyword(EnteredKeywordModeMethod entered_method) { |
763 DCHECK(is_keyword_hint_ && !keyword_.empty()); | 765 DCHECK(is_keyword_hint_ && !keyword_.empty()); |
764 | 766 |
765 autocomplete_controller()->Stop(false); | 767 autocomplete_controller()->Stop(false); |
766 is_keyword_hint_ = false; | 768 is_keyword_hint_ = false; |
767 | 769 |
768 if (popup_->IsOpen()) | 770 if (popup_model()->IsOpen()) |
769 popup_->SetSelectedLineState(OmniboxPopupModel::KEYWORD); | 771 popup_model()->SetSelectedLineState(OmniboxPopupModel::KEYWORD); |
770 else | 772 else |
771 StartAutocomplete(false, true); | 773 StartAutocomplete(false, true); |
772 | 774 |
773 // Ensure the current selection is saved before showing keyword mode | 775 // Ensure the current selection is saved before showing keyword mode |
774 // so that moving to another line and then reverting the text will restore | 776 // so that moving to another line and then reverting the text will restore |
775 // the current state properly. | 777 // the current state properly. |
776 bool save_original_selection = !has_temporary_text_; | 778 bool save_original_selection = !has_temporary_text_; |
777 has_temporary_text_ = true; | 779 has_temporary_text_ = true; |
778 is_temporary_text_set_by_instant_ = false; | 780 is_temporary_text_set_by_instant_ = false; |
779 is_instant_temporary_text_a_search_query_ = false; | 781 is_instant_temporary_text_a_search_query_ = false; |
780 view_->OnTemporaryTextMaybeChanged( | 782 view_->OnTemporaryTextMaybeChanged( |
781 DisplayTextFromUserText(CurrentMatch().fill_into_edit), | 783 DisplayTextFromUserText(CurrentMatch().fill_into_edit), |
782 save_original_selection, true); | 784 save_original_selection, true); |
783 | 785 |
784 content::RecordAction(UserMetricsAction("AcceptedKeywordHint")); | 786 content::RecordAction(UserMetricsAction("AcceptedKeywordHint")); |
785 UMA_HISTOGRAM_ENUMERATION(kEnteredKeywordModeHistogram, entered_method, | 787 UMA_HISTOGRAM_ENUMERATION(kEnteredKeywordModeHistogram, entered_method, |
786 ENTERED_KEYWORD_MODE_NUM_ITEMS); | 788 ENTERED_KEYWORD_MODE_NUM_ITEMS); |
787 | 789 |
788 return true; | 790 return true; |
789 } | 791 } |
790 | 792 |
793 void OmniboxEditModel::AcceptTemporaryTextAsUserText() { | |
794 InternalSetUserText(UserTextFromDisplayText(view_->GetText())); | |
795 has_temporary_text_ = false; | |
796 is_temporary_text_set_by_instant_ = false; | |
797 OnPopupBoundsChanged(gfx::Rect()); | |
798 delegate_->NotifySearchTabHelper(user_input_in_progress_, !in_revert_); | |
799 } | |
800 | |
791 void OmniboxEditModel::ClearKeyword(const string16& visible_text) { | 801 void OmniboxEditModel::ClearKeyword(const string16& visible_text) { |
792 autocomplete_controller()->Stop(false); | 802 autocomplete_controller()->Stop(false); |
793 ClearPopupKeywordMode(); | 803 omnibox_controller_->ClearPopupKeywordMode(); |
794 | 804 |
795 const string16 window_text(keyword_ + visible_text); | 805 const string16 window_text(keyword_ + visible_text); |
796 | 806 |
797 // Only reset the result if the edit text has changed since the | 807 // Only reset the result if the edit text has changed since the |
798 // keyword was accepted, or if the popup is closed. | 808 // keyword was accepted, or if the popup is closed. |
799 if (just_deleted_text_ || !visible_text.empty() || !popup_->IsOpen()) { | 809 if (just_deleted_text_ || !visible_text.empty() || !popup_model()->IsOpen()) { |
800 view_->OnBeforePossibleChange(); | 810 view_->OnBeforePossibleChange(); |
801 view_->SetWindowTextAndCaretPos(window_text.c_str(), keyword_.length(), | 811 view_->SetWindowTextAndCaretPos(window_text.c_str(), keyword_.length(), |
802 false, false); | 812 false, false); |
803 keyword_.clear(); | 813 keyword_.clear(); |
804 is_keyword_hint_ = false; | 814 is_keyword_hint_ = false; |
805 view_->OnAfterPossibleChange(); | 815 view_->OnAfterPossibleChange(); |
806 just_deleted_text_ = true; // OnAfterPossibleChange() fails to clear this | 816 just_deleted_text_ = true; // OnAfterPossibleChange() fails to clear this |
807 // since the edit contents have actually grown | 817 // since the edit contents have actually grown |
808 // longer. | 818 // longer. |
809 } else { | 819 } else { |
810 is_keyword_hint_ = true; | 820 is_keyword_hint_ = true; |
811 view_->SetWindowTextAndCaretPos(window_text.c_str(), keyword_.length(), | 821 view_->SetWindowTextAndCaretPos(window_text.c_str(), keyword_.length(), |
812 false, true); | 822 false, true); |
813 } | 823 } |
814 } | 824 } |
815 | 825 |
816 const AutocompleteResult& OmniboxEditModel::result() const { | |
817 return autocomplete_controller()->result(); | |
818 } | |
819 | |
820 void OmniboxEditModel::OnSetFocus(bool control_down) { | 826 void OmniboxEditModel::OnSetFocus(bool control_down) { |
821 // If the omnibox lost focus while the caret was hidden and then regained | 827 // If the omnibox lost focus while the caret was hidden and then regained |
822 // focus, OnSetFocus() is called and should restore visibility. Note that | 828 // focus, OnSetFocus() is called and should restore visibility. Note that |
823 // focus can be regained without an accompanying call to | 829 // focus can be regained without an accompanying call to |
824 // OmniboxView::SetFocus(), e.g. by tabbing in. | 830 // OmniboxView::SetFocus(), e.g. by tabbing in. |
825 SetFocusState(OMNIBOX_FOCUS_VISIBLE, OMNIBOX_FOCUS_CHANGE_EXPLICIT); | 831 SetFocusState(OMNIBOX_FOCUS_VISIBLE, OMNIBOX_FOCUS_CHANGE_EXPLICIT); |
826 control_key_state_ = control_down ? DOWN_WITHOUT_CHANGE : UP; | 832 control_key_state_ = control_down ? DOWN_WITHOUT_CHANGE : UP; |
827 | 833 |
828 if (delegate_->CurrentPageExists()) { | 834 if (delegate_->CurrentPageExists()) { |
829 // TODO(jered): We may want to merge this into Start() and just call that | 835 // TODO(jered): We may want to merge this into Start() and just call that |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
911 ControlKeyState old_state = control_key_state_; | 917 ControlKeyState old_state = control_key_state_; |
912 control_key_state_ = pressed ? DOWN_WITHOUT_CHANGE : UP; | 918 control_key_state_ = pressed ? DOWN_WITHOUT_CHANGE : UP; |
913 if ((control_key_state_ == DOWN_WITHOUT_CHANGE) && has_temporary_text_) { | 919 if ((control_key_state_ == DOWN_WITHOUT_CHANGE) && has_temporary_text_) { |
914 // Arrowing down and then hitting control accepts the temporary text as | 920 // Arrowing down and then hitting control accepts the temporary text as |
915 // the input text. | 921 // the input text. |
916 InternalSetUserText(UserTextFromDisplayText(view_->GetText())); | 922 InternalSetUserText(UserTextFromDisplayText(view_->GetText())); |
917 has_temporary_text_ = false; | 923 has_temporary_text_ = false; |
918 is_temporary_text_set_by_instant_ = false; | 924 is_temporary_text_set_by_instant_ = false; |
919 is_instant_temporary_text_a_search_query_ = false; | 925 is_instant_temporary_text_a_search_query_ = false; |
920 } | 926 } |
921 if ((old_state != DOWN_WITH_CHANGE) && popup_->IsOpen()) { | 927 if ((old_state != DOWN_WITH_CHANGE) && popup_model()->IsOpen()) { |
922 // Autocomplete history provider results may change, so refresh the | 928 // Autocomplete history provider results may change, so refresh the |
923 // popup. This will force user_input_in_progress_ to true, but if the | 929 // popup. This will force user_input_in_progress_ to true, but if the |
924 // popup is open, that should have already been the case. | 930 // popup is open, that should have already been the case. |
925 view_->UpdatePopup(); | 931 view_->UpdatePopup(); |
926 } | 932 } |
927 } | 933 } |
928 } | 934 } |
929 | 935 |
930 void OmniboxEditModel::OnUpOrDownKeyPressed(int count) { | 936 void OmniboxEditModel::OnUpOrDownKeyPressed(int count) { |
931 // NOTE: This purposefully doesn't trigger any code that resets paste_state_. | 937 // NOTE: This purposefully doesn't trigger any code that resets paste_state_. |
932 if (!popup_->IsOpen()) { | 938 if (!popup_model()->IsOpen()) { |
933 if (!query_in_progress()) { | 939 if (!query_in_progress()) { |
934 // The popup is neither open nor working on a query already. So, start an | 940 // The popup is neither open nor working on a query already. So, start an |
935 // autocomplete query for the current text. This also sets | 941 // autocomplete query for the current text. This also sets |
936 // user_input_in_progress_ to true, which we want: if the user has started | 942 // user_input_in_progress_ to true, which we want: if the user has started |
937 // to interact with the popup, changing the permanent_text_ shouldn't | 943 // to interact with the popup, changing the permanent_text_ shouldn't |
938 // change the displayed text. | 944 // change the displayed text. |
939 // Note: This does not force the popup to open immediately. | 945 // Note: This does not force the popup to open immediately. |
940 // TODO(pkasting): We should, in fact, force this particular query to open | 946 // TODO(pkasting): We should, in fact, force this particular query to open |
941 // the popup immediately. | 947 // the popup immediately. |
942 if (!user_input_in_progress_) | 948 if (!user_input_in_progress_) |
943 InternalSetUserText(permanent_text_); | 949 InternalSetUserText(permanent_text_); |
944 view_->UpdatePopup(); | 950 view_->UpdatePopup(); |
945 } else { | 951 } else { |
946 // TODO(pkasting): The popup is working on a query but is not open. We | 952 // TODO(pkasting): The popup is working on a query but is not open. We |
947 // should force it to open immediately. | 953 // should force it to open immediately. |
948 } | 954 } |
949 } else { | 955 } else { |
950 InstantController* instant = controller_->GetInstant(); | 956 InstantController* instant = controller_->GetInstant(); |
951 if (instant && instant->OnUpOrDownKeyPressed(count)) { | 957 if (instant && instant->OnUpOrDownKeyPressed(count)) { |
952 // If Instant handles the key press, it's showing a list of suggestions | 958 // If Instant handles the key press, it's showing a list of suggestions |
953 // that it's stepping through. In that case, our popup model is | 959 // that it's stepping through. In that case, our popup model is |
954 // irrelevant, so don't process the key press ourselves. However, do stop | 960 // irrelevant, so don't process the key press ourselves. However, do stop |
955 // the autocomplete system from changing the results. | 961 // the autocomplete system from changing the results. |
956 autocomplete_controller()->Stop(false); | 962 autocomplete_controller()->Stop(false); |
957 } else { | 963 } else { |
958 // The popup is open, so the user should be able to interact with it | 964 // The popup is open, so the user should be able to interact with it |
959 // normally. | 965 // normally. |
960 popup_->Move(count); | 966 popup_model()->Move(count); |
961 } | 967 } |
962 } | 968 } |
963 } | 969 } |
964 | 970 |
965 void OmniboxEditModel::OnPopupDataChanged( | 971 void OmniboxEditModel::OnPopupDataChanged( |
966 const string16& text, | 972 const string16& text, |
967 GURL* destination_for_temporary_text_change, | 973 GURL* destination_for_temporary_text_change, |
968 const string16& keyword, | 974 const string16& keyword, |
969 bool is_keyword_hint) { | 975 bool is_keyword_hint) { |
976 DLOG(ERROR) << "A"; | |
Mathieu
2013/05/03 19:09:02
remove
beaudoin
2013/05/04 03:06:51
/facepalm. :)
Done.
| |
970 // Update keyword/hint-related local state. | 977 // Update keyword/hint-related local state. |
971 bool keyword_state_changed = (keyword_ != keyword) || | 978 bool keyword_state_changed = (keyword_ != keyword) || |
972 ((is_keyword_hint_ != is_keyword_hint) && !keyword.empty()); | 979 ((is_keyword_hint_ != is_keyword_hint) && !keyword.empty()); |
973 if (keyword_state_changed) { | 980 if (keyword_state_changed) { |
974 keyword_ = keyword; | 981 keyword_ = keyword; |
975 is_keyword_hint_ = is_keyword_hint; | 982 is_keyword_hint_ = is_keyword_hint; |
976 | 983 |
977 // |is_keyword_hint_| should always be false if |keyword_| is empty. | 984 // |is_keyword_hint_| should always be false if |keyword_| is empty. |
978 DCHECK(!keyword_.empty() || !is_keyword_hint_); | 985 DCHECK(!keyword_.empty() || !is_keyword_hint_); |
979 } | 986 } |
980 | 987 |
988 DLOG(ERROR) << "B"; | |
981 // Handle changes to temporary text. | 989 // Handle changes to temporary text. |
982 if (destination_for_temporary_text_change != NULL) { | 990 if (destination_for_temporary_text_change != NULL) { |
983 const bool save_original_selection = !has_temporary_text_; | 991 const bool save_original_selection = !has_temporary_text_; |
984 if (save_original_selection) { | 992 if (save_original_selection) { |
985 // Save the original selection and URL so it can be reverted later. | 993 // Save the original selection and URL so it can be reverted later. |
986 has_temporary_text_ = true; | 994 has_temporary_text_ = true; |
987 is_temporary_text_set_by_instant_ = false; | 995 is_temporary_text_set_by_instant_ = false; |
988 is_instant_temporary_text_a_search_query_ = false; | 996 is_instant_temporary_text_a_search_query_ = false; |
989 original_url_ = *destination_for_temporary_text_change; | 997 original_url_ = *destination_for_temporary_text_change; |
990 inline_autocomplete_text_.clear(); | 998 inline_autocomplete_text_.clear(); |
991 } | 999 } |
1000 DLOG(ERROR) << "C"; | |
992 if (control_key_state_ == DOWN_WITHOUT_CHANGE) { | 1001 if (control_key_state_ == DOWN_WITHOUT_CHANGE) { |
993 // Arrowing around the popup cancels control-enter. | 1002 // Arrowing around the popup cancels control-enter. |
994 control_key_state_ = DOWN_WITH_CHANGE; | 1003 control_key_state_ = DOWN_WITH_CHANGE; |
995 // Now things are a bit screwy: the desired_tld has changed, but if we | 1004 // Now things are a bit screwy: the desired_tld has changed, but if we |
996 // update the popup, the new order of entries won't match the old, so the | 1005 // update the popup, the new order of entries won't match the old, so the |
997 // user's selection gets screwy; and if we don't update the popup, and the | 1006 // user's selection gets screwy; and if we don't update the popup, and the |
998 // user reverts, then the selected item will be as if control is still | 1007 // user reverts, then the selected item will be as if control is still |
999 // pressed, even though maybe it isn't any more. There is no obvious | 1008 // pressed, even though maybe it isn't any more. There is no obvious |
1000 // right answer here :( | 1009 // right answer here :( |
1001 } | 1010 } |
1011 DLOG(ERROR) << "D"; | |
1002 view_->OnTemporaryTextMaybeChanged(DisplayTextFromUserText(text), | 1012 view_->OnTemporaryTextMaybeChanged(DisplayTextFromUserText(text), |
1003 save_original_selection, true); | 1013 save_original_selection, true); |
1004 return; | 1014 return; |
1005 } | 1015 } |
1016 DLOG(ERROR) << "E: " << keyword_state_changed; | |
1006 | 1017 |
1007 bool call_controller_onchanged = true; | 1018 bool call_controller_onchanged = true; |
1008 inline_autocomplete_text_ = text; | 1019 inline_autocomplete_text_ = text; |
1009 | 1020 |
1010 if (keyword_state_changed && KeywordIsSelected()) { | 1021 if (keyword_state_changed && KeywordIsSelected()) { |
1011 // If we reach here, the user most likely entered keyword mode by inserting | 1022 // If we reach here, the user most likely entered keyword mode by inserting |
1012 // a space between a keyword name and a search string (as pressing space or | 1023 // a space between a keyword name and a search string (as pressing space or |
1013 // tab after the keyword name alone would have been be handled in | 1024 // tab after the keyword name alone would have been be handled in |
1014 // MaybeAcceptKeywordBySpace() by calling AcceptKeyword(), which won't reach | 1025 // MaybeAcceptKeywordBySpace() by calling AcceptKeyword(), which won't reach |
1015 // here). In this case, we don't want to call | 1026 // here). In this case, we don't want to call |
1016 // OnInlineAutocompleteTextMaybeChanged() as normal, because that will | 1027 // OnInlineAutocompleteTextMaybeChanged() as normal, because that will |
1017 // correctly change the text (to the search string alone) but move the caret | 1028 // correctly change the text (to the search string alone) but move the caret |
1018 // to the end of the string; instead we want the caret at the start of the | 1029 // to the end of the string; instead we want the caret at the start of the |
1019 // search string since that's where it was in the original input. So we set | 1030 // search string since that's where it was in the original input. So we set |
1020 // the text and caret position directly. | 1031 // the text and caret position directly. |
1021 // | 1032 // |
1022 // It may also be possible to reach here if we're reverting from having | 1033 // It may also be possible to reach here if we're reverting from having |
1023 // temporary text back to a default match that's a keyword search, but in | 1034 // temporary text back to a default match that's a keyword search, but in |
1024 // that case the RevertTemporaryText() call below will reset the caret or | 1035 // that case the RevertTemporaryText() call below will reset the caret or |
1025 // selection correctly so the caret positioning we do here won't matter. | 1036 // selection correctly so the caret positioning we do here won't matter. |
1037 DLOG(ERROR) << "F"; | |
1026 view_->SetWindowTextAndCaretPos(DisplayTextFromUserText(user_text_), 0, | 1038 view_->SetWindowTextAndCaretPos(DisplayTextFromUserText(user_text_), 0, |
1027 false, false); | 1039 false, false); |
1028 } else if (view_->OnInlineAutocompleteTextMaybeChanged( | 1040 } else if (view_->OnInlineAutocompleteTextMaybeChanged( |
1029 DisplayTextFromUserText(user_text_ + inline_autocomplete_text_), | 1041 DisplayTextFromUserText(user_text_ + inline_autocomplete_text_), |
1030 DisplayTextFromUserText(user_text_).length())) { | 1042 DisplayTextFromUserText(user_text_).length())) { |
1043 DLOG(ERROR) << "G"; | |
1031 call_controller_onchanged = false; | 1044 call_controller_onchanged = false; |
1032 } | 1045 } |
1033 | 1046 |
1034 // If |has_temporary_text_| is true, then we previously had a manual selection | 1047 // If |has_temporary_text_| is true, then we previously had a manual selection |
1035 // but now don't (or |destination_for_temporary_text_change| would have been | 1048 // but now don't (or |destination_for_temporary_text_change| would have been |
1036 // non-NULL). This can happen when deleting the selected item in the popup. | 1049 // non-NULL). This can happen when deleting the selected item in the popup. |
1037 // In this case, we've already reverted the popup to the default match, so we | 1050 // In this case, we've already reverted the popup to the default match, so we |
1038 // need to revert ourselves as well. | 1051 // need to revert ourselves as well. |
1052 DLOG(ERROR) << "H"; | |
1039 if (has_temporary_text_) { | 1053 if (has_temporary_text_) { |
1040 RevertTemporaryText(false); | 1054 RevertTemporaryText(false); |
1041 call_controller_onchanged = false; | 1055 call_controller_onchanged = false; |
1042 } | 1056 } |
1043 | 1057 |
1058 DLOG(ERROR) << "I"; | |
1044 // We need to invoke OnChanged in case the destination url changed (as could | 1059 // We need to invoke OnChanged in case the destination url changed (as could |
1045 // happen when control is toggled). | 1060 // happen when control is toggled). |
1046 if (call_controller_onchanged) | 1061 if (call_controller_onchanged) |
1047 OnChanged(); | 1062 OnChanged(); |
1048 } | 1063 } |
1049 | 1064 |
1050 bool OmniboxEditModel::OnAfterPossibleChange(const string16& old_text, | 1065 bool OmniboxEditModel::OnAfterPossibleChange(const string16& old_text, |
1051 const string16& new_text, | 1066 const string16& new_text, |
1052 size_t selection_start, | 1067 size_t selection_start, |
1053 size_t selection_end, | 1068 size_t selection_end, |
(...skipping 17 matching lines...) Expand all Loading... | |
1071 // Modifying the selection counts as accepting the autocompleted text. | 1086 // Modifying the selection counts as accepting the autocompleted text. |
1072 const bool user_text_changed = | 1087 const bool user_text_changed = |
1073 text_differs || (selection_differs && !inline_autocomplete_text_.empty()); | 1088 text_differs || (selection_differs && !inline_autocomplete_text_.empty()); |
1074 | 1089 |
1075 // If something has changed while the control key is down, prevent | 1090 // If something has changed while the control key is down, prevent |
1076 // "ctrl-enter" until the control key is released. When we do this, we need | 1091 // "ctrl-enter" until the control key is released. When we do this, we need |
1077 // to update the popup if it's open, since the desired_tld will have changed. | 1092 // to update the popup if it's open, since the desired_tld will have changed. |
1078 if ((text_differs || selection_differs) && | 1093 if ((text_differs || selection_differs) && |
1079 (control_key_state_ == DOWN_WITHOUT_CHANGE)) { | 1094 (control_key_state_ == DOWN_WITHOUT_CHANGE)) { |
1080 control_key_state_ = DOWN_WITH_CHANGE; | 1095 control_key_state_ = DOWN_WITH_CHANGE; |
1081 if (!text_differs && !popup_->IsOpen()) | 1096 if (!text_differs && !popup_model()->IsOpen()) |
1082 return false; // Don't open the popup for no reason. | 1097 return false; // Don't open the popup for no reason. |
1083 } else if (!user_text_changed) { | 1098 } else if (!user_text_changed) { |
1084 return false; | 1099 return false; |
1085 } | 1100 } |
1086 | 1101 |
1087 // If the user text has not changed, we do not want to change the model's | 1102 // If the user text has not changed, we do not want to change the model's |
1088 // state associated with the text. Otherwise, we can get surprising behavior | 1103 // state associated with the text. Otherwise, we can get surprising behavior |
1089 // where the autocompleted text unexpectedly reappears, e.g. crbug.com/55983 | 1104 // where the autocompleted text unexpectedly reappears, e.g. crbug.com/55983 |
1090 if (user_text_changed) { | 1105 if (user_text_changed) { |
1091 InternalSetUserText(UserTextFromDisplayText(new_text)); | 1106 InternalSetUserText(UserTextFromDisplayText(new_text)); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1143 MaybeAcceptKeywordBySpace(user_text_)); | 1158 MaybeAcceptKeywordBySpace(user_text_)); |
1144 } | 1159 } |
1145 | 1160 |
1146 void OmniboxEditModel::OnPopupBoundsChanged(const gfx::Rect& bounds) { | 1161 void OmniboxEditModel::OnPopupBoundsChanged(const gfx::Rect& bounds) { |
1147 InstantController* instant = controller_->GetInstant(); | 1162 InstantController* instant = controller_->GetInstant(); |
1148 if (instant) | 1163 if (instant) |
1149 instant->SetPopupBounds(bounds); | 1164 instant->SetPopupBounds(bounds); |
1150 } | 1165 } |
1151 | 1166 |
1152 void OmniboxEditModel::OnResultChanged(bool default_match_changed) { | 1167 void OmniboxEditModel::OnResultChanged(bool default_match_changed) { |
1153 const bool was_open = popup_->IsOpen(); | |
1154 if (default_match_changed) { | |
1155 string16 inline_autocomplete_text; | |
1156 string16 keyword; | |
1157 bool is_keyword_hint = false; | |
1158 const AutocompleteResult& result = this->result(); | |
1159 const AutocompleteResult::const_iterator match(result.default_match()); | |
1160 if (match != result.end()) { | |
1161 if ((match->inline_autocomplete_offset != string16::npos) && | |
1162 (match->inline_autocomplete_offset < | |
1163 match->fill_into_edit.length())) { | |
1164 inline_autocomplete_text = | |
1165 match->fill_into_edit.substr(match->inline_autocomplete_offset); | |
1166 } | |
1167 | |
1168 if (!prerender::IsOmniboxEnabled(profile_)) | |
1169 DoPreconnect(*match); | |
1170 | |
1171 // We could prefetch the alternate nav URL, if any, but because there | |
1172 // can be many of these as a user types an initial series of characters, | |
1173 // the OS DNS cache could suffer eviction problems for minimal gain. | |
1174 | |
1175 match->GetKeywordUIState(profile_, &keyword, &is_keyword_hint); | |
1176 } | |
1177 | |
1178 popup_->OnResultChanged(); | |
1179 OnPopupDataChanged(inline_autocomplete_text, NULL, keyword, | |
1180 is_keyword_hint); | |
1181 } else { | |
1182 popup_->OnResultChanged(); | |
1183 } | |
1184 | |
1185 if (popup_->IsOpen()) { | |
1186 OnPopupBoundsChanged(popup_->view()->GetTargetBounds()); | |
1187 | |
1188 InstantController* instant = controller_->GetInstant(); | |
1189 if (instant && !in_revert_) { | |
1190 instant->HandleAutocompleteResults( | |
1191 *autocomplete_controller()->providers()); | |
1192 } | |
1193 } else if (was_open) { | |
1194 // Accepts the temporary text as the user text, because it makes little | |
1195 // sense to have temporary text when the popup is closed. | |
1196 InternalSetUserText(UserTextFromDisplayText(view_->GetText())); | |
1197 has_temporary_text_ = false; | |
1198 is_temporary_text_set_by_instant_ = false; | |
1199 is_instant_temporary_text_a_search_query_ = false; | |
1200 OnPopupBoundsChanged(gfx::Rect()); | |
1201 delegate_->NotifySearchTabHelper(user_input_in_progress_, !in_revert_); | |
1202 } | |
1203 } | 1168 } |
1204 | 1169 |
1205 bool OmniboxEditModel::query_in_progress() const { | 1170 bool OmniboxEditModel::query_in_progress() const { |
1206 return !autocomplete_controller()->done(); | 1171 return !autocomplete_controller()->done(); |
1207 } | 1172 } |
1208 | 1173 |
1209 void OmniboxEditModel::InternalSetUserText(const string16& text) { | 1174 void OmniboxEditModel::InternalSetUserText(const string16& text) { |
1210 user_text_ = text; | 1175 user_text_ = text; |
1211 just_deleted_text_ = false; | 1176 just_deleted_text_ = false; |
1212 inline_autocomplete_text_.clear(); | 1177 inline_autocomplete_text_.clear(); |
1213 } | 1178 } |
1214 | 1179 |
1215 bool OmniboxEditModel::KeywordIsSelected() const { | 1180 bool OmniboxEditModel::KeywordIsSelected() const { |
1216 return !is_keyword_hint_ && !keyword_.empty(); | 1181 return !is_keyword_hint_ && !keyword_.empty(); |
1217 } | 1182 } |
1218 | 1183 |
1219 void OmniboxEditModel::ClearPopupKeywordMode() const { | |
1220 if (popup_->IsOpen() && | |
1221 popup_->selected_line_state() == OmniboxPopupModel::KEYWORD) | |
1222 popup_->SetSelectedLineState(OmniboxPopupModel::NORMAL); | |
1223 } | |
1224 | |
1225 string16 OmniboxEditModel::DisplayTextFromUserText(const string16& text) const { | 1184 string16 OmniboxEditModel::DisplayTextFromUserText(const string16& text) const { |
1226 return KeywordIsSelected() ? | 1185 return KeywordIsSelected() ? |
1227 KeywordProvider::SplitReplacementStringFromInput(text, false) : text; | 1186 KeywordProvider::SplitReplacementStringFromInput(text, false) : text; |
1228 } | 1187 } |
1229 | 1188 |
1230 string16 OmniboxEditModel::UserTextFromDisplayText(const string16& text) const { | 1189 string16 OmniboxEditModel::UserTextFromDisplayText(const string16& text) const { |
1231 return KeywordIsSelected() ? (keyword_ + char16(' ') + text) : text; | 1190 return KeywordIsSelected() ? (keyword_ + char16(' ') + text) : text; |
1232 } | 1191 } |
1233 | 1192 |
1234 void OmniboxEditModel::InfoForCurrentSelection(AutocompleteMatch* match, | |
1235 GURL* alternate_nav_url) const { | |
1236 DCHECK(match != NULL); | |
1237 const AutocompleteResult& result = this->result(); | |
1238 if (!autocomplete_controller()->done()) { | |
1239 // It's technically possible for |result| to be empty if no provider returns | |
1240 // a synchronous result but the query has not completed synchronously; | |
1241 // pratically, however, that should never actually happen. | |
1242 if (result.empty()) | |
1243 return; | |
1244 // The user cannot have manually selected a match, or the query would have | |
1245 // stopped. So the default match must be the desired selection. | |
1246 *match = *result.default_match(); | |
1247 } else { | |
1248 CHECK(popup_->IsOpen()); | |
1249 // If there are no results, the popup should be closed (so we should have | |
1250 // failed the CHECK above), and URLsForDefaultMatch() should have been | |
1251 // called instead. | |
1252 CHECK(!result.empty()); | |
1253 CHECK(popup_->selected_line() < result.size()); | |
1254 *match = result.match_at(popup_->selected_line()); | |
1255 } | |
1256 if (alternate_nav_url && popup_->manually_selected_match().empty()) | |
1257 *alternate_nav_url = result.alternate_nav_url(); | |
1258 } | |
1259 | |
1260 void OmniboxEditModel::GetInfoForCurrentText(AutocompleteMatch* match, | 1193 void OmniboxEditModel::GetInfoForCurrentText(AutocompleteMatch* match, |
1261 GURL* alternate_nav_url) const { | 1194 GURL* alternate_nav_url) const { |
1262 // If there's temporary text and it has been set by Instant, we won't find it | 1195 // If there's temporary text and it has been set by Instant, we won't find it |
1263 // in the popup model, so create the match based on the type Instant told us | 1196 // in the popup model, so classify the text anew. |
1264 // (SWYT for queries and UWYT for URLs). We do this instead of classifying the | 1197 if ((popup_model()->IsOpen() || query_in_progress()) && |
1265 // text ourselves because the text may look like a URL, but Instant may expect | 1198 !is_temporary_text_set_by_instant_) { |
1266 // it to be a search (e.g.: a query for "amazon.com"). | |
1267 if (is_temporary_text_set_by_instant_) { | |
1268 const string16& text = view_->GetText(); | |
1269 AutocompleteInput input(text, string16::npos, string16(), GURL(), false, | |
1270 false, false, AutocompleteInput::BEST_MATCH); | |
1271 // Only the destination_url and the transition of the match will be be used | |
1272 // (to either navigate to the URL or let Instant commit its preview). The | |
1273 // match won't be used for logging, displaying in the dropdown, etc. So, | |
1274 // it's okay to pass in mostly bogus params (such as relevance = 0). | |
1275 // TODO(sreeram): Always using NO_SUGGESTIONS_AVAILABLE is wrong when | |
1276 // Instant is using the local fallback overlay. Fix. | |
1277 if (is_instant_temporary_text_a_search_query_) { | |
1278 const TemplateURL* default_provider = | |
1279 TemplateURLServiceFactory::GetForProfile(profile_)-> | |
1280 GetDefaultSearchProvider(); | |
1281 if (default_provider && default_provider->SupportsReplacement()) { | |
1282 *match = SearchProvider::CreateSearchSuggestion(profile_, | |
1283 autocomplete_controller()->search_provider(), input, text, text, 0, | |
1284 AutocompleteMatch::SEARCH_WHAT_YOU_TYPED, | |
1285 TemplateURLRef::NO_SUGGESTIONS_AVAILABLE, false, | |
1286 default_provider->keyword()); | |
1287 } else { | |
1288 // Can't create a new search match. Leave |match| as is, with an | |
1289 // invalid destination_url. This shouldn't ever happen. For example, | |
1290 // even if a group policy update in the midst of interacting with | |
1291 // Instant leaves us without a valid search provider, Instant should've | |
1292 // observed the update and reset |is_temporary_text_set_by_instant_|, | |
1293 // so we still shouldn't get here. However, as protection against the | |
1294 // unknowns and Instant regressions, we simply return an invalid match | |
1295 // instead of crashing (hence no DCHECK). | |
1296 } | |
1297 } else { | |
1298 *match = HistoryURLProvider::SuggestExactInput( | |
1299 autocomplete_controller()->history_url_provider(), input, false); | |
1300 } | |
1301 } else if (popup_->IsOpen() || query_in_progress()) { | |
1302 InfoForCurrentSelection(match, alternate_nav_url); | 1199 InfoForCurrentSelection(match, alternate_nav_url); |
1303 } else { | 1200 } else { |
1304 AutocompleteClassifierFactory::GetForProfile(profile_)->Classify( | 1201 AutocompleteClassifierFactory::GetForProfile(profile_)->Classify( |
1305 UserTextFromDisplayText(view_->GetText()), KeywordIsSelected(), true, | 1202 UserTextFromDisplayText(view_->GetText()), KeywordIsSelected(), true, |
1306 match, alternate_nav_url); | 1203 match, alternate_nav_url); |
1307 } | 1204 } |
1308 } | 1205 } |
1309 | 1206 |
1310 void OmniboxEditModel::RevertTemporaryText(bool revert_popup) { | 1207 void OmniboxEditModel::RevertTemporaryText(bool revert_popup) { |
1311 // The user typed something, then selected a different item. Restore the | 1208 // The user typed something, then selected a different item. Restore the |
(...skipping 17 matching lines...) Expand all Loading... | |
1329 // The two "false" arguments make sure that our shenanigans don't cause any | 1226 // The two "false" arguments make sure that our shenanigans don't cause any |
1330 // previously saved selection to be erased nor OnChanged() to be called. | 1227 // previously saved selection to be erased nor OnChanged() to be called. |
1331 view_->OnTemporaryTextMaybeChanged(user_text_ + inline_autocomplete_text_, | 1228 view_->OnTemporaryTextMaybeChanged(user_text_ + inline_autocomplete_text_, |
1332 false, false); | 1229 false, false); |
1333 AutocompleteResult::const_iterator match(result().default_match()); | 1230 AutocompleteResult::const_iterator match(result().default_match()); |
1334 instant->OnCancel(match != result().end() ? *match : AutocompleteMatch(), | 1231 instant->OnCancel(match != result().end() ? *match : AutocompleteMatch(), |
1335 user_text_, | 1232 user_text_, |
1336 user_text_ + inline_autocomplete_text_); | 1233 user_text_ + inline_autocomplete_text_); |
1337 } | 1234 } |
1338 if (revert_popup) | 1235 if (revert_popup) |
1339 popup_->ResetToDefaultMatch(); | 1236 popup_model()->ResetToDefaultMatch(); |
1340 view_->OnRevertTemporaryText(); | 1237 view_->OnRevertTemporaryText(); |
1341 } | 1238 } |
1342 | 1239 |
1343 bool OmniboxEditModel::MaybeAcceptKeywordBySpace(const string16& new_text) { | 1240 bool OmniboxEditModel::MaybeAcceptKeywordBySpace(const string16& new_text) { |
1344 size_t keyword_length = new_text.length() - 1; | 1241 size_t keyword_length = new_text.length() - 1; |
1345 return (paste_state_ == NONE) && is_keyword_hint_ && !keyword_.empty() && | 1242 return (paste_state_ == NONE) && is_keyword_hint_ && !keyword_.empty() && |
1346 inline_autocomplete_text_.empty() && | 1243 inline_autocomplete_text_.empty() && |
1347 (keyword_.length() == keyword_length) && | 1244 (keyword_.length() == keyword_length) && |
1348 IsSpaceCharForAcceptingKeyword(new_text[keyword_length]) && | 1245 IsSpaceCharForAcceptingKeyword(new_text[keyword_length]) && |
1349 !new_text.compare(0, keyword_length, keyword_, 0, keyword_length) && | 1246 !new_text.compare(0, keyword_length, keyword_, 0, keyword_length) && |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1400 // Remove "?" if we're in forced query mode. | 1297 // Remove "?" if we're in forced query mode. |
1401 AutocompleteInput::RemoveForcedQueryStringIfNecessary( | 1298 AutocompleteInput::RemoveForcedQueryStringIfNecessary( |
1402 autocomplete_controller()->input().type(), &user_text); | 1299 autocomplete_controller()->input().type(), &user_text); |
1403 AutocompleteInput::RemoveForcedQueryStringIfNecessary( | 1300 AutocompleteInput::RemoveForcedQueryStringIfNecessary( |
1404 autocomplete_controller()->input().type(), &full_text); | 1301 autocomplete_controller()->input().type(), &full_text); |
1405 | 1302 |
1406 size_t start, end; | 1303 size_t start, end; |
1407 view_->GetSelectionBounds(&start, &end); | 1304 view_->GetSelectionBounds(&start, &end); |
1408 | 1305 |
1409 return instant->Update(match, user_text, full_text, start, end, | 1306 return instant->Update(match, user_text, full_text, start, end, |
1410 UseVerbatimInstant(), user_input_in_progress_, popup_->IsOpen(), | 1307 UseVerbatimInstant(), user_input_in_progress_, popup_model()->IsOpen(), |
1411 in_escape_handler_, KeywordIsSelected()); | 1308 in_escape_handler_, KeywordIsSelected()); |
1412 } | 1309 } |
1413 | 1310 |
1414 void OmniboxEditModel::DoPreconnect(const AutocompleteMatch& match) { | |
1415 if (!match.destination_url.SchemeIs(extensions::kExtensionScheme)) { | |
1416 // Warm up DNS Prefetch cache, or preconnect to a search service. | |
1417 UMA_HISTOGRAM_ENUMERATION("Autocomplete.MatchType", match.type, | |
1418 AutocompleteMatch::NUM_TYPES); | |
1419 if (profile_->GetNetworkPredictor()) { | |
1420 profile_->GetNetworkPredictor()->AnticipateOmniboxUrl( | |
1421 match.destination_url, | |
1422 AutocompleteActionPredictor::IsPreconnectable(match)); | |
1423 } | |
1424 // We could prefetch the alternate nav URL, if any, but because there | |
1425 // can be many of these as a user types an initial series of characters, | |
1426 // the OS DNS cache could suffer eviction problems for minimal gain. | |
1427 } | |
1428 } | |
1429 | |
1430 // static | 1311 // static |
1431 bool OmniboxEditModel::IsSpaceCharForAcceptingKeyword(wchar_t c) { | 1312 bool OmniboxEditModel::IsSpaceCharForAcceptingKeyword(wchar_t c) { |
1432 switch (c) { | 1313 switch (c) { |
1433 case 0x0020: // Space | 1314 case 0x0020: // Space |
1434 case 0x3000: // Ideographic Space | 1315 case 0x3000: // Ideographic Space |
1435 return true; | 1316 return true; |
1436 default: | 1317 default: |
1437 return false; | 1318 return false; |
1438 } | 1319 } |
1439 } | 1320 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1471 instant->OmniboxFocusChanged(state, reason, NULL); | 1352 instant->OmniboxFocusChanged(state, reason, NULL); |
1472 | 1353 |
1473 // Update state and notify view if the omnibox has focus and the caret | 1354 // Update state and notify view if the omnibox has focus and the caret |
1474 // visibility changed. | 1355 // visibility changed. |
1475 const bool was_caret_visible = is_caret_visible(); | 1356 const bool was_caret_visible = is_caret_visible(); |
1476 focus_state_ = state; | 1357 focus_state_ = state; |
1477 if (focus_state_ != OMNIBOX_FOCUS_NONE && | 1358 if (focus_state_ != OMNIBOX_FOCUS_NONE && |
1478 is_caret_visible() != was_caret_visible) | 1359 is_caret_visible() != was_caret_visible) |
1479 view_->ApplyCaretVisibility(); | 1360 view_->ApplyCaretVisibility(); |
1480 } | 1361 } |
OLD | NEW |