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 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
127 just_deleted_text_(false), | 127 just_deleted_text_(false), |
128 has_temporary_text_(false), | 128 has_temporary_text_(false), |
129 is_temporary_text_set_by_instant_(false), | 129 is_temporary_text_set_by_instant_(false), |
130 paste_state_(NONE), | 130 paste_state_(NONE), |
131 control_key_state_(UP), | 131 control_key_state_(UP), |
132 is_keyword_hint_(false), | 132 is_keyword_hint_(false), |
133 profile_(profile), | 133 profile_(profile), |
134 in_revert_(false), | 134 in_revert_(false), |
135 in_escape_handler_(false), | 135 in_escape_handler_(false), |
136 allow_exact_keyword_match_(false) { | 136 allow_exact_keyword_match_(false) { |
137 // Use a restricted subset of the autocomplete providers if we're using the | 137 omnibox_controller_.reset(new OmniboxController(this, profile)); |
138 // Instant Extended API, as it doesn't support them all. | |
139 autocomplete_controller_.reset(new AutocompleteController(profile, this, | |
140 chrome::IsInstantExtendedAPIEnabled() ? | |
141 AutocompleteClassifier::kInstantExtendedOmniboxProviders : | |
142 AutocompleteClassifier::kDefaultOmniboxProviders)); | |
143 delegate_.reset(new OmniboxCurrentPageDelegateImpl(controller, profile)); | 138 delegate_.reset(new OmniboxCurrentPageDelegateImpl(controller, profile)); |
144 } | 139 } |
145 | 140 |
146 OmniboxEditModel::~OmniboxEditModel() { | 141 OmniboxEditModel::~OmniboxEditModel() { |
147 } | 142 } |
148 | 143 |
149 const OmniboxEditModel::State OmniboxEditModel::GetStateForTabSwitch() { | 144 const OmniboxEditModel::State OmniboxEditModel::GetStateForTabSwitch() { |
150 // Like typing, switching tabs "accepts" the temporary text as the user | 145 // Like typing, switching tabs "accepts" the temporary text as the user |
151 // text, because it makes little sense to have temporary text when the | 146 // text, because it makes little sense to have temporary text when the |
152 // popup is closed. | 147 // popup is closed. |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
231 const InstantSuggestion& suggestion, | 226 const InstantSuggestion& suggestion, |
232 bool skip_inline_autocomplete) { | 227 bool skip_inline_autocomplete) { |
233 if (skip_inline_autocomplete) { | 228 if (skip_inline_autocomplete) { |
234 const string16 final_text = input_text + suggestion.text; | 229 const string16 final_text = input_text + suggestion.text; |
235 view_->OnBeforePossibleChange(); | 230 view_->OnBeforePossibleChange(); |
236 view_->SetWindowTextAndCaretPos(final_text, final_text.length(), false, | 231 view_->SetWindowTextAndCaretPos(final_text, final_text.length(), false, |
237 false); | 232 false); |
238 view_->OnAfterPossibleChange(); | 233 view_->OnAfterPossibleChange(); |
239 } else if (popup_->IsOpen()) { | 234 } else if (popup_->IsOpen()) { |
240 SearchProvider* search_provider = | 235 SearchProvider* search_provider = |
241 autocomplete_controller_->search_provider(); | 236 autocomplete_controller()->search_provider(); |
242 // There may be no providers during testing; guard against that. | 237 // There may be no providers during testing; guard against that. |
243 if (search_provider) | 238 if (search_provider) |
244 search_provider->FinalizeInstantQuery(input_text, suggestion); | 239 search_provider->FinalizeInstantQuery(input_text, suggestion); |
245 } | 240 } |
246 } | 241 } |
247 | 242 |
248 void OmniboxEditModel::SetInstantSuggestion( | 243 void OmniboxEditModel::SetInstantSuggestion( |
249 const InstantSuggestion& suggestion) { | 244 const InstantSuggestion& suggestion) { |
250 switch (suggestion.behavior) { | 245 switch (suggestion.behavior) { |
251 case INSTANT_COMPLETE_NOW: | 246 case INSTANT_COMPLETE_NOW: |
252 view_->SetInstantSuggestion(string16()); | 247 view_->SetInstantSuggestion(string16()); |
253 if (!suggestion.text.empty()) | 248 if (!suggestion.text.empty()) |
254 FinalizeInstantQuery(view_->GetText(), suggestion, false); | 249 FinalizeInstantQuery(view_->GetText(), suggestion, false); |
255 break; | 250 break; |
256 | 251 |
257 case INSTANT_COMPLETE_NEVER: { | 252 case INSTANT_COMPLETE_NEVER: { |
258 DCHECK_EQ(INSTANT_SUGGESTION_SEARCH, suggestion.type); | 253 DCHECK_EQ(INSTANT_SUGGESTION_SEARCH, suggestion.type); |
259 view_->SetInstantSuggestion(suggestion.text); | 254 view_->SetInstantSuggestion(suggestion.text); |
260 SearchProvider* search_provider = | 255 SearchProvider* search_provider = |
261 autocomplete_controller_->search_provider(); | 256 autocomplete_controller()->search_provider(); |
262 if (search_provider) | 257 if (search_provider) |
263 search_provider->ClearInstantSuggestion(); | 258 search_provider->ClearInstantSuggestion(); |
264 break; | 259 break; |
265 } | 260 } |
266 | 261 |
267 case INSTANT_COMPLETE_REPLACE: { | 262 case INSTANT_COMPLETE_REPLACE: { |
268 const bool save_original_selection = !has_temporary_text_; | 263 const bool save_original_selection = !has_temporary_text_; |
269 view_->SetInstantSuggestion(string16()); | 264 view_->SetInstantSuggestion(string16()); |
270 has_temporary_text_ = true; | 265 has_temporary_text_ = true; |
271 is_temporary_text_set_by_instant_ = true; | 266 is_temporary_text_set_by_instant_ = true; |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
365 std::string())) { | 360 std::string())) { |
366 *title = controller_->GetTitle(); | 361 *title = controller_->GetTitle(); |
367 *favicon = controller_->GetFavicon(); | 362 *favicon = controller_->GetFavicon(); |
368 } | 363 } |
369 } | 364 } |
370 | 365 |
371 bool OmniboxEditModel::UseVerbatimInstant() { | 366 bool OmniboxEditModel::UseVerbatimInstant() { |
372 #if defined(OS_MACOSX) | 367 #if defined(OS_MACOSX) |
373 // TODO(suzhe): Fix Mac port to display Instant suggest in a separated NSView, | 368 // TODO(suzhe): Fix Mac port to display Instant suggest in a separated NSView, |
374 // so that we can display Instant suggest along with composition text. | 369 // so that we can display Instant suggest along with composition text. |
375 const AutocompleteInput& input = autocomplete_controller_->input(); | 370 const AutocompleteInput& input = autocomplete_controller()->input(); |
376 if (input.prevent_inline_autocomplete()) | 371 if (input.prevent_inline_autocomplete()) |
377 return true; | 372 return true; |
378 #endif | 373 #endif |
379 | 374 |
380 // The value of input.prevent_inline_autocomplete() is determined by the | 375 // The value of input.prevent_inline_autocomplete() is determined by the |
381 // following conditions: | 376 // following conditions: |
382 // 1. If the caret is at the end of the text. | 377 // 1. If the caret is at the end of the text. |
383 // 2. If it's in IME composition mode. | 378 // 2. If it's in IME composition mode. |
384 // We send the caret position to Instant (so it can determine #1 itself), and | 379 // We send the caret position to Instant (so it can determine #1 itself), and |
385 // we use a separated widget for displaying the Instant suggest (so it doesn't | 380 // we use a separated widget for displaying the Instant suggest (so it doesn't |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
461 } | 456 } |
462 | 457 |
463 void OmniboxEditModel::SetInputInProgress(bool in_progress) { | 458 void OmniboxEditModel::SetInputInProgress(bool in_progress) { |
464 if (user_input_in_progress_ == in_progress) | 459 if (user_input_in_progress_ == in_progress) |
465 return; | 460 return; |
466 | 461 |
467 user_input_in_progress_ = in_progress; | 462 user_input_in_progress_ = in_progress; |
468 if (user_input_in_progress_) { | 463 if (user_input_in_progress_) { |
469 time_user_first_modified_omnibox_ = base::TimeTicks::Now(); | 464 time_user_first_modified_omnibox_ = base::TimeTicks::Now(); |
470 content::RecordAction(content::UserMetricsAction("OmniboxInputInProgress")); | 465 content::RecordAction(content::UserMetricsAction("OmniboxInputInProgress")); |
471 autocomplete_controller_->ResetSession(); | 466 autocomplete_controller()->ResetSession(); |
472 } | 467 } |
473 controller_->OnInputInProgress(in_progress); | 468 controller_->OnInputInProgress(in_progress); |
474 | 469 |
475 delegate_->NotifySearchTabHelper(user_input_in_progress_, !in_revert_); | 470 delegate_->NotifySearchTabHelper(user_input_in_progress_, !in_revert_); |
476 } | 471 } |
477 | 472 |
478 void OmniboxEditModel::Revert() { | 473 void OmniboxEditModel::Revert() { |
479 SetInputInProgress(false); | 474 SetInputInProgress(false); |
480 paste_state_ = NONE; | 475 paste_state_ = NONE; |
481 InternalSetUserText(string16()); | 476 InternalSetUserText(string16()); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
520 // One example is when user presses Ctrl key while having a highlighted | 515 // One example is when user presses Ctrl key while having a highlighted |
521 // inline autocomplete text. | 516 // inline autocomplete text. |
522 // TODO: Rethink how we are going to handle this case to avoid | 517 // TODO: Rethink how we are going to handle this case to avoid |
523 // inconsistent behavior when user presses Ctrl key. | 518 // inconsistent behavior when user presses Ctrl key. |
524 // See http://crbug.com/165961 and http://crbug.com/165968 for more details. | 519 // See http://crbug.com/165961 and http://crbug.com/165968 for more details. |
525 cursor_position = user_text_.length(); | 520 cursor_position = user_text_.length(); |
526 } | 521 } |
527 | 522 |
528 // We don't explicitly clear OmniboxPopupModel::manually_selected_match, as | 523 // We don't explicitly clear OmniboxPopupModel::manually_selected_match, as |
529 // Start ends up invoking OmniboxPopupModel::OnResultChanged which clears it. | 524 // Start ends up invoking OmniboxPopupModel::OnResultChanged which clears it. |
530 autocomplete_controller_->Start(AutocompleteInput( | 525 autocomplete_controller()->Start(AutocompleteInput( |
531 user_text_, cursor_position, string16(), GURL(), | 526 user_text_, cursor_position, string16(), GURL(), |
532 prevent_inline_autocomplete || just_deleted_text_ || | 527 prevent_inline_autocomplete || just_deleted_text_ || |
533 (has_selected_text && inline_autocomplete_text_.empty()) || | 528 (has_selected_text && inline_autocomplete_text_.empty()) || |
534 (paste_state_ != NONE), keyword_is_selected, | 529 (paste_state_ != NONE), keyword_is_selected, |
535 keyword_is_selected || allow_exact_keyword_match_, | 530 keyword_is_selected || allow_exact_keyword_match_, |
536 AutocompleteInput::ALL_MATCHES)); | 531 AutocompleteInput::ALL_MATCHES)); |
537 } | 532 } |
538 | 533 |
539 void OmniboxEditModel::StopAutocomplete() { | 534 void OmniboxEditModel::StopAutocomplete() { |
540 autocomplete_controller_->Stop(true); | 535 autocomplete_controller()->Stop(true); |
541 } | 536 } |
542 | 537 |
543 bool OmniboxEditModel::CanPasteAndGo(const string16& text) const { | 538 bool OmniboxEditModel::CanPasteAndGo(const string16& text) const { |
544 if (!view_->command_updater()->IsCommandEnabled(IDC_OPEN_CURRENT_URL)) | 539 if (!view_->command_updater()->IsCommandEnabled(IDC_OPEN_CURRENT_URL)) |
545 return false; | 540 return false; |
546 | 541 |
547 AutocompleteMatch match; | 542 AutocompleteMatch match; |
548 ClassifyStringForPasteAndGo(text, &match, NULL); | 543 ClassifyStringForPasteAndGo(text, &match, NULL); |
549 return match.destination_url.is_valid(); | 544 return match.destination_url.is_valid(); |
550 } | 545 } |
(...skipping 19 matching lines...) Expand all Loading... |
570 // Get the URL and transition type for the selected entry. | 565 // Get the URL and transition type for the selected entry. |
571 AutocompleteMatch match; | 566 AutocompleteMatch match; |
572 GURL alternate_nav_url; | 567 GURL alternate_nav_url; |
573 GetInfoForCurrentText(&match, &alternate_nav_url); | 568 GetInfoForCurrentText(&match, &alternate_nav_url); |
574 | 569 |
575 // If CTRL is down it means the user wants to append ".com" to the text he | 570 // If CTRL is down it means the user wants to append ".com" to the text he |
576 // typed. If we can successfully generate a URL_WHAT_YOU_TYPED match doing | 571 // typed. If we can successfully generate a URL_WHAT_YOU_TYPED match doing |
577 // that, then we use this. These matches are marked as generated by the | 572 // that, then we use this. These matches are marked as generated by the |
578 // HistoryURLProvider so we only generate them if this provider is present. | 573 // HistoryURLProvider so we only generate them if this provider is present. |
579 if (control_key_state_ == DOWN_WITHOUT_CHANGE && !KeywordIsSelected() && | 574 if (control_key_state_ == DOWN_WITHOUT_CHANGE && !KeywordIsSelected() && |
580 autocomplete_controller_->history_url_provider()) { | 575 autocomplete_controller()->history_url_provider()) { |
581 // Generate a new AutocompleteInput, copying the latest one but using "com" | 576 // Generate a new AutocompleteInput, copying the latest one but using "com" |
582 // as the desired TLD. Then use this autocomplete input to generate a | 577 // as the desired TLD. Then use this autocomplete input to generate a |
583 // URL_WHAT_YOU_TYPED AutocompleteMatch. Note that using the most recent | 578 // URL_WHAT_YOU_TYPED AutocompleteMatch. Note that using the most recent |
584 // input instead of the currently visible text means we'll ignore any | 579 // input instead of the currently visible text means we'll ignore any |
585 // visible inline autocompletion: if a user types "foo" and is autocompleted | 580 // visible inline autocompletion: if a user types "foo" and is autocompleted |
586 // to "foodnetwork.com", ctrl-enter will navigate to "foo.com", not | 581 // to "foodnetwork.com", ctrl-enter will navigate to "foo.com", not |
587 // "foodnetwork.com". At the time of writing, this behavior matches | 582 // "foodnetwork.com". At the time of writing, this behavior matches |
588 // Internet Explorer, but not Firefox. | 583 // Internet Explorer, but not Firefox. |
589 const AutocompleteInput& old_input = autocomplete_controller_->input(); | 584 const AutocompleteInput& old_input = autocomplete_controller()->input(); |
590 AutocompleteInput input( | 585 AutocompleteInput input( |
591 old_input.text(), old_input.cursor_position(), ASCIIToUTF16("com"), | 586 old_input.text(), old_input.cursor_position(), ASCIIToUTF16("com"), |
592 GURL(), old_input.prevent_inline_autocomplete(), | 587 GURL(), old_input.prevent_inline_autocomplete(), |
593 old_input.prefer_keyword(), old_input.allow_exact_keyword_match(), | 588 old_input.prefer_keyword(), old_input.allow_exact_keyword_match(), |
594 old_input.matches_requested()); | 589 old_input.matches_requested()); |
595 AutocompleteMatch url_match = HistoryURLProvider::SuggestExactInput( | 590 AutocompleteMatch url_match = HistoryURLProvider::SuggestExactInput( |
596 autocomplete_controller_->history_url_provider(), input, true); | 591 autocomplete_controller()->history_url_provider(), input, true); |
597 | 592 |
598 if (url_match.destination_url.is_valid()) { | 593 if (url_match.destination_url.is_valid()) { |
599 // We have a valid URL, we use this newly generated AutocompleteMatch. | 594 // We have a valid URL, we use this newly generated AutocompleteMatch. |
600 match = url_match; | 595 match = url_match; |
601 alternate_nav_url = GURL(); | 596 alternate_nav_url = GURL(); |
602 } | 597 } |
603 } | 598 } |
604 | 599 |
605 if (!match.destination_url.is_valid()) | 600 if (!match.destination_url.is_valid()) |
606 return; | 601 return; |
(...skipping 30 matching lines...) Expand all Loading... |
637 void OmniboxEditModel::OpenMatch(const AutocompleteMatch& match, | 632 void OmniboxEditModel::OpenMatch(const AutocompleteMatch& match, |
638 WindowOpenDisposition disposition, | 633 WindowOpenDisposition disposition, |
639 const GURL& alternate_nav_url, | 634 const GURL& alternate_nav_url, |
640 size_t index) { | 635 size_t index) { |
641 // We only care about cases where there is a selection (i.e. the popup is | 636 // We only care about cases where there is a selection (i.e. the popup is |
642 // open). | 637 // open). |
643 if (popup_->IsOpen()) { | 638 if (popup_->IsOpen()) { |
644 const base::TimeTicks& now(base::TimeTicks::Now()); | 639 const base::TimeTicks& now(base::TimeTicks::Now()); |
645 // TODO(sreeram): Handle is_temporary_text_set_by_instant_ correctly. | 640 // TODO(sreeram): Handle is_temporary_text_set_by_instant_ correctly. |
646 AutocompleteLog log( | 641 AutocompleteLog log( |
647 autocomplete_controller_->input().text(), | 642 autocomplete_controller()->input().text(), |
648 just_deleted_text_, | 643 just_deleted_text_, |
649 autocomplete_controller_->input().type(), | 644 autocomplete_controller()->input().type(), |
650 popup_->selected_line(), | 645 popup_->selected_line(), |
651 -1, // don't yet know tab ID; set later if appropriate | 646 -1, // don't yet know tab ID; set later if appropriate |
652 delegate_->CurrentPageExists() ? ClassifyPage(delegate_->GetURL()) : | 647 delegate_->CurrentPageExists() ? ClassifyPage(delegate_->GetURL()) : |
653 metrics::OmniboxEventProto_PageClassification_OTHER, | 648 metrics::OmniboxEventProto_PageClassification_OTHER, |
654 now - time_user_first_modified_omnibox_, | 649 now - time_user_first_modified_omnibox_, |
655 string16::npos, // completed_length; possibly set later | 650 string16::npos, // completed_length; possibly set later |
656 now - autocomplete_controller_->last_time_default_match_changed(), | 651 now - autocomplete_controller()->last_time_default_match_changed(), |
657 result()); | 652 result()); |
658 DCHECK(user_input_in_progress_ || | 653 DCHECK(user_input_in_progress_ || |
659 match.provider->type() == AutocompleteProvider::TYPE_ZERO_SUGGEST) | 654 match.provider->type() == AutocompleteProvider::TYPE_ZERO_SUGGEST) |
660 << "We didn't get here through the expected series of calls. " | 655 << "We didn't get here through the expected series of calls. " |
661 << "time_user_first_modified_omnibox_ is not set correctly and other " | 656 << "time_user_first_modified_omnibox_ is not set correctly and other " |
662 << "things may be wrong. Match provider: " << match.provider->GetName(); | 657 << "things may be wrong. Match provider: " << match.provider->GetName(); |
663 DCHECK(log.elapsed_time_since_user_first_modified_omnibox >= | 658 DCHECK(log.elapsed_time_since_user_first_modified_omnibox >= |
664 log.elapsed_time_since_last_change_to_default_match) | 659 log.elapsed_time_since_last_change_to_default_match) |
665 << "We should've got the notification that the user modified the " | 660 << "We should've got the notification that the user modified the " |
666 << "omnibox text at same time or before the most recent time the " | 661 << "omnibox text at same time or before the most recent time the " |
667 << "default match changed."; | 662 << "default match changed."; |
668 if (index != OmniboxPopupModel::kNoMatch) | 663 if (index != OmniboxPopupModel::kNoMatch) |
669 log.selected_index = index; | 664 log.selected_index = index; |
670 if (match.inline_autocomplete_offset != string16::npos) { | 665 if (match.inline_autocomplete_offset != string16::npos) { |
671 DCHECK_GE(match.fill_into_edit.length(), | 666 DCHECK_GE(match.fill_into_edit.length(), |
672 match.inline_autocomplete_offset); | 667 match.inline_autocomplete_offset); |
673 log.completed_length = | 668 log.completed_length = |
674 match.fill_into_edit.length() - match.inline_autocomplete_offset; | 669 match.fill_into_edit.length() - match.inline_autocomplete_offset; |
675 } | 670 } |
676 | 671 |
677 if ((disposition == CURRENT_TAB) && delegate_->CurrentPageExists()) { | 672 if ((disposition == CURRENT_TAB) && delegate_->CurrentPageExists()) { |
678 // If we know the destination is being opened in the current tab, | 673 // If we know the destination is being opened in the current tab, |
679 // we can easily get the tab ID. (If it's being opened in a new | 674 // we can easily get the tab ID. (If it's being opened in a new |
680 // tab, we don't know the tab ID yet.) | 675 // tab, we don't know the tab ID yet.) |
681 log.tab_id = delegate_->GetSessionID().id(); | 676 log.tab_id = delegate_->GetSessionID().id(); |
682 } | 677 } |
683 autocomplete_controller_->AddProvidersInfo(&log.providers_info); | 678 autocomplete_controller()->AddProvidersInfo(&log.providers_info); |
684 content::NotificationService::current()->Notify( | 679 content::NotificationService::current()->Notify( |
685 chrome::NOTIFICATION_OMNIBOX_OPENED_URL, | 680 chrome::NOTIFICATION_OMNIBOX_OPENED_URL, |
686 content::Source<Profile>(profile_), | 681 content::Source<Profile>(profile_), |
687 content::Details<AutocompleteLog>(&log)); | 682 content::Details<AutocompleteLog>(&log)); |
688 HISTOGRAM_ENUMERATION("Omnibox.EventCount", 1, 2); | 683 HISTOGRAM_ENUMERATION("Omnibox.EventCount", 1, 2); |
689 } | 684 } |
690 | 685 |
691 TemplateURL* template_url = match.GetTemplateURL(profile_, false); | 686 TemplateURL* template_url = match.GetTemplateURL(profile_, false); |
692 if (template_url) { | 687 if (template_url) { |
693 if (match.transition == content::PAGE_TRANSITION_KEYWORD) { | 688 if (match.transition == content::PAGE_TRANSITION_KEYWORD) { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
728 if (disposition != NEW_BACKGROUND_TAB) { | 723 if (disposition != NEW_BACKGROUND_TAB) { |
729 base::AutoReset<bool> tmp(&in_revert_, true); | 724 base::AutoReset<bool> tmp(&in_revert_, true); |
730 view_->RevertAll(); // Revert the box to its unedited state | 725 view_->RevertAll(); // Revert the box to its unedited state |
731 } | 726 } |
732 | 727 |
733 if (match.type == AutocompleteMatch::EXTENSION_APP) { | 728 if (match.type == AutocompleteMatch::EXTENSION_APP) { |
734 ExtensionAppProvider::LaunchAppFromOmnibox(match, profile_, disposition); | 729 ExtensionAppProvider::LaunchAppFromOmnibox(match, profile_, disposition); |
735 } else { | 730 } else { |
736 base::TimeDelta query_formulation_time = | 731 base::TimeDelta query_formulation_time = |
737 base::TimeTicks::Now() - time_user_first_modified_omnibox_; | 732 base::TimeTicks::Now() - time_user_first_modified_omnibox_; |
738 const GURL destination_url = autocomplete_controller_-> | 733 const GURL destination_url = autocomplete_controller()-> |
739 GetDestinationURL(match, query_formulation_time); | 734 GetDestinationURL(match, query_formulation_time); |
740 | 735 |
741 // If running with instant, notify the instant controller that a navigation | 736 // If running with instant, notify the instant controller that a navigation |
742 // is about to take place if we are navigating to a URL. This can be | 737 // is about to take place if we are navigating to a URL. This can be |
743 // determined by inspecting the transition type. To ensure that this is only | 738 // determined by inspecting the transition type. To ensure that this is only |
744 // done on Enter key press, check that the disposition is CURRENT_TAB. This | 739 // done on Enter key press, check that the disposition is CURRENT_TAB. This |
745 // is the same heuristic used by BrowserInstantController::OpenInstant | 740 // is the same heuristic used by BrowserInstantController::OpenInstant |
746 if (match.transition == content::PAGE_TRANSITION_TYPED && | 741 if (match.transition == content::PAGE_TRANSITION_TYPED && |
747 disposition == CURRENT_TAB) { | 742 disposition == CURRENT_TAB) { |
748 InstantController* instant = controller_->GetInstant(); | 743 InstantController* instant = controller_->GetInstant(); |
749 if (instant) | 744 if (instant) |
750 instant->OmniboxNavigateToURL(); | 745 instant->OmniboxNavigateToURL(); |
751 } | 746 } |
752 | 747 |
753 // This calls RevertAll again. | 748 // This calls RevertAll again. |
754 base::AutoReset<bool> tmp(&in_revert_, true); | 749 base::AutoReset<bool> tmp(&in_revert_, true); |
755 controller_->OnAutocompleteAccept(destination_url, disposition, | 750 controller_->OnAutocompleteAccept(destination_url, disposition, |
756 match.transition, alternate_nav_url); | 751 match.transition, alternate_nav_url); |
757 } | 752 } |
758 | 753 |
759 if (match.starred) | 754 if (match.starred) |
760 bookmark_utils::RecordBookmarkLaunch(bookmark_utils::LAUNCH_OMNIBOX); | 755 bookmark_utils::RecordBookmarkLaunch(bookmark_utils::LAUNCH_OMNIBOX); |
761 } | 756 } |
762 | 757 |
763 bool OmniboxEditModel::AcceptKeyword(EnteredKeywordModeMethod entered_method) { | 758 bool OmniboxEditModel::AcceptKeyword(EnteredKeywordModeMethod entered_method) { |
764 DCHECK(is_keyword_hint_ && !keyword_.empty()); | 759 DCHECK(is_keyword_hint_ && !keyword_.empty()); |
765 | 760 |
766 autocomplete_controller_->Stop(false); | 761 autocomplete_controller()->Stop(false); |
767 is_keyword_hint_ = false; | 762 is_keyword_hint_ = false; |
768 | 763 |
769 if (popup_->IsOpen()) | 764 if (popup_->IsOpen()) |
770 popup_->SetSelectedLineState(OmniboxPopupModel::KEYWORD); | 765 popup_->SetSelectedLineState(OmniboxPopupModel::KEYWORD); |
771 else | 766 else |
772 StartAutocomplete(false, true); | 767 StartAutocomplete(false, true); |
773 | 768 |
774 // Ensure the current selection is saved before showing keyword mode | 769 // Ensure the current selection is saved before showing keyword mode |
775 // so that moving to another line and then reverting the text will restore | 770 // so that moving to another line and then reverting the text will restore |
776 // the current state properly. | 771 // the current state properly. |
777 bool save_original_selection = !has_temporary_text_; | 772 bool save_original_selection = !has_temporary_text_; |
778 has_temporary_text_ = true; | 773 has_temporary_text_ = true; |
779 is_temporary_text_set_by_instant_ = false; | 774 is_temporary_text_set_by_instant_ = false; |
780 view_->OnTemporaryTextMaybeChanged( | 775 view_->OnTemporaryTextMaybeChanged( |
781 DisplayTextFromUserText(CurrentMatch().fill_into_edit), | 776 DisplayTextFromUserText(CurrentMatch().fill_into_edit), |
782 save_original_selection, true); | 777 save_original_selection, true); |
783 | 778 |
784 content::RecordAction(UserMetricsAction("AcceptedKeywordHint")); | 779 content::RecordAction(UserMetricsAction("AcceptedKeywordHint")); |
785 UMA_HISTOGRAM_ENUMERATION(kEnteredKeywordModeHistogram, entered_method, | 780 UMA_HISTOGRAM_ENUMERATION(kEnteredKeywordModeHistogram, entered_method, |
786 ENTERED_KEYWORD_MODE_NUM_ITEMS); | 781 ENTERED_KEYWORD_MODE_NUM_ITEMS); |
787 | 782 |
788 return true; | 783 return true; |
789 } | 784 } |
790 | 785 |
791 void OmniboxEditModel::ClearKeyword(const string16& visible_text) { | 786 void OmniboxEditModel::ClearKeyword(const string16& visible_text) { |
792 autocomplete_controller_->Stop(false); | 787 autocomplete_controller()->Stop(false); |
793 ClearPopupKeywordMode(); | 788 ClearPopupKeywordMode(); |
794 | 789 |
795 const string16 window_text(keyword_ + visible_text); | 790 const string16 window_text(keyword_ + visible_text); |
796 | 791 |
797 // Only reset the result if the edit text has changed since the | 792 // Only reset the result if the edit text has changed since the |
798 // keyword was accepted, or if the popup is closed. | 793 // keyword was accepted, or if the popup is closed. |
799 if (just_deleted_text_ || !visible_text.empty() || !popup_->IsOpen()) { | 794 if (just_deleted_text_ || !visible_text.empty() || !popup_->IsOpen()) { |
800 view_->OnBeforePossibleChange(); | 795 view_->OnBeforePossibleChange(); |
801 view_->SetWindowTextAndCaretPos(window_text.c_str(), keyword_.length(), | 796 view_->SetWindowTextAndCaretPos(window_text.c_str(), keyword_.length(), |
802 false, false); | 797 false, false); |
803 keyword_.clear(); | 798 keyword_.clear(); |
804 is_keyword_hint_ = false; | 799 is_keyword_hint_ = false; |
805 view_->OnAfterPossibleChange(); | 800 view_->OnAfterPossibleChange(); |
806 just_deleted_text_ = true; // OnAfterPossibleChange() fails to clear this | 801 just_deleted_text_ = true; // OnAfterPossibleChange() fails to clear this |
807 // since the edit contents have actually grown | 802 // since the edit contents have actually grown |
808 // longer. | 803 // longer. |
809 } else { | 804 } else { |
810 is_keyword_hint_ = true; | 805 is_keyword_hint_ = true; |
811 view_->SetWindowTextAndCaretPos(window_text.c_str(), keyword_.length(), | 806 view_->SetWindowTextAndCaretPos(window_text.c_str(), keyword_.length(), |
812 false, true); | 807 false, true); |
813 } | 808 } |
814 } | 809 } |
815 | 810 |
816 const AutocompleteResult& OmniboxEditModel::result() const { | 811 const AutocompleteResult& OmniboxEditModel::result() const { |
817 return autocomplete_controller_->result(); | 812 return autocomplete_controller()->result(); |
818 } | 813 } |
819 | 814 |
820 void OmniboxEditModel::OnSetFocus(bool control_down) { | 815 void OmniboxEditModel::OnSetFocus(bool control_down) { |
821 // If the omnibox lost focus while the caret was hidden and then regained | 816 // If the omnibox lost focus while the caret was hidden and then regained |
822 // focus, OnSetFocus() is called and should restore visibility. Note that | 817 // focus, OnSetFocus() is called and should restore visibility. Note that |
823 // focus can be regained without an accompanying call to | 818 // focus can be regained without an accompanying call to |
824 // OmniboxView::SetFocus(), e.g. by tabbing in. | 819 // OmniboxView::SetFocus(), e.g. by tabbing in. |
825 SetFocusState(OMNIBOX_FOCUS_VISIBLE, OMNIBOX_FOCUS_CHANGE_EXPLICIT); | 820 SetFocusState(OMNIBOX_FOCUS_VISIBLE, OMNIBOX_FOCUS_CHANGE_EXPLICIT); |
826 control_key_state_ = control_down ? DOWN_WITHOUT_CHANGE : UP; | 821 control_key_state_ = control_down ? DOWN_WITHOUT_CHANGE : UP; |
827 | 822 |
828 if (delegate_->CurrentPageExists()) { | 823 if (delegate_->CurrentPageExists()) { |
829 // TODO(jered): We may want to merge this into Start() and just call that | 824 // TODO(jered): We may want to merge this into Start() and just call that |
830 // here rather than having a special entry point for zero-suggest. Note | 825 // here rather than having a special entry point for zero-suggest. Note |
831 // that we avoid PermanentURL() here because it's not guaranteed to give us | 826 // that we avoid PermanentURL() here because it's not guaranteed to give us |
832 // the actual underlying current URL, e.g. if we're on the NTP and the | 827 // the actual underlying current URL, e.g. if we're on the NTP and the |
833 // |permanent_text_| is empty. | 828 // |permanent_text_| is empty. |
834 autocomplete_controller_->StartZeroSuggest(delegate_->GetURL(), | 829 autocomplete_controller()->StartZeroSuggest(delegate_->GetURL(), |
835 user_text_); | 830 user_text_); |
836 } | 831 } |
837 | 832 |
838 delegate_->NotifySearchTabHelper(user_input_in_progress_, !in_revert_); | 833 delegate_->NotifySearchTabHelper(user_input_in_progress_, !in_revert_); |
839 } | 834 } |
840 | 835 |
841 void OmniboxEditModel::SetCaretVisibility(bool visible) { | 836 void OmniboxEditModel::SetCaretVisibility(bool visible) { |
842 // Caret visibility only matters if the omnibox has focus. | 837 // Caret visibility only matters if the omnibox has focus. |
843 if (focus_state_ != OMNIBOX_FOCUS_NONE) { | 838 if (focus_state_ != OMNIBOX_FOCUS_NONE) { |
844 SetFocusState(visible ? OMNIBOX_FOCUS_VISIBLE : OMNIBOX_FOCUS_INVISIBLE, | 839 SetFocusState(visible ? OMNIBOX_FOCUS_VISIBLE : OMNIBOX_FOCUS_INVISIBLE, |
845 OMNIBOX_FOCUS_CHANGE_EXPLICIT); | 840 OMNIBOX_FOCUS_CHANGE_EXPLICIT); |
846 } | 841 } |
847 } | 842 } |
848 | 843 |
849 void OmniboxEditModel::OnWillKillFocus(gfx::NativeView view_gaining_focus) { | 844 void OmniboxEditModel::OnWillKillFocus(gfx::NativeView view_gaining_focus) { |
850 InstantController* instant = controller_->GetInstant(); | 845 InstantController* instant = controller_->GetInstant(); |
851 if (instant) { | 846 if (instant) { |
852 instant->OmniboxFocusChanged(OMNIBOX_FOCUS_NONE, | 847 instant->OmniboxFocusChanged(OMNIBOX_FOCUS_NONE, |
853 OMNIBOX_FOCUS_CHANGE_EXPLICIT, | 848 OMNIBOX_FOCUS_CHANGE_EXPLICIT, |
854 view_gaining_focus); | 849 view_gaining_focus); |
855 } | 850 } |
856 | 851 |
857 // TODO(jered): Rip this out along with StartZeroSuggest. | 852 // TODO(jered): Rip this out along with StartZeroSuggest. |
858 autocomplete_controller_->StopZeroSuggest(); | 853 autocomplete_controller()->StopZeroSuggest(); |
859 delegate_->NotifySearchTabHelper(user_input_in_progress_, !in_revert_); | 854 delegate_->NotifySearchTabHelper(user_input_in_progress_, !in_revert_); |
860 } | 855 } |
861 | 856 |
862 void OmniboxEditModel::OnKillFocus() { | 857 void OmniboxEditModel::OnKillFocus() { |
863 // TODO(samarth): determine if it is safe to move the call to | 858 // TODO(samarth): determine if it is safe to move the call to |
864 // OmniboxFocusChanged() from OnWillKillFocus() to here, which would let us | 859 // OmniboxFocusChanged() from OnWillKillFocus() to here, which would let us |
865 // just call SetFocusState() to handle the state change. | 860 // just call SetFocusState() to handle the state change. |
866 focus_state_ = OMNIBOX_FOCUS_NONE; | 861 focus_state_ = OMNIBOX_FOCUS_NONE; |
867 control_key_state_ = UP; | 862 control_key_state_ = UP; |
868 paste_state_ = NONE; | 863 paste_state_ = NONE; |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
945 // TODO(pkasting): The popup is working on a query but is not open. We | 940 // TODO(pkasting): The popup is working on a query but is not open. We |
946 // should force it to open immediately. | 941 // should force it to open immediately. |
947 } | 942 } |
948 } else { | 943 } else { |
949 InstantController* instant = controller_->GetInstant(); | 944 InstantController* instant = controller_->GetInstant(); |
950 if (instant && instant->OnUpOrDownKeyPressed(count)) { | 945 if (instant && instant->OnUpOrDownKeyPressed(count)) { |
951 // If Instant handles the key press, it's showing a list of suggestions | 946 // If Instant handles the key press, it's showing a list of suggestions |
952 // that it's stepping through. In that case, our popup model is | 947 // that it's stepping through. In that case, our popup model is |
953 // irrelevant, so don't process the key press ourselves. However, do stop | 948 // irrelevant, so don't process the key press ourselves. However, do stop |
954 // the autocomplete system from changing the results. | 949 // the autocomplete system from changing the results. |
955 autocomplete_controller_->Stop(false); | 950 autocomplete_controller()->Stop(false); |
956 } else { | 951 } else { |
957 // The popup is open, so the user should be able to interact with it | 952 // The popup is open, so the user should be able to interact with it |
958 // normally. | 953 // normally. |
959 popup_->Move(count); | 954 popup_->Move(count); |
960 } | 955 } |
961 } | 956 } |
962 } | 957 } |
963 | 958 |
964 void OmniboxEditModel::OnPopupDataChanged( | 959 void OmniboxEditModel::OnPopupDataChanged( |
965 const string16& text, | 960 const string16& text, |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1178 } else { | 1173 } else { |
1179 popup_->OnResultChanged(); | 1174 popup_->OnResultChanged(); |
1180 } | 1175 } |
1181 | 1176 |
1182 if (popup_->IsOpen()) { | 1177 if (popup_->IsOpen()) { |
1183 OnPopupBoundsChanged(popup_->view()->GetTargetBounds()); | 1178 OnPopupBoundsChanged(popup_->view()->GetTargetBounds()); |
1184 | 1179 |
1185 InstantController* instant = controller_->GetInstant(); | 1180 InstantController* instant = controller_->GetInstant(); |
1186 if (instant && !in_revert_) { | 1181 if (instant && !in_revert_) { |
1187 instant->HandleAutocompleteResults( | 1182 instant->HandleAutocompleteResults( |
1188 *autocomplete_controller_->providers()); | 1183 *autocomplete_controller()->providers()); |
1189 } | 1184 } |
1190 } else if (was_open) { | 1185 } else if (was_open) { |
1191 // Accepts the temporary text as the user text, because it makes little | 1186 // Accepts the temporary text as the user text, because it makes little |
1192 // sense to have temporary text when the popup is closed. | 1187 // sense to have temporary text when the popup is closed. |
1193 InternalSetUserText(UserTextFromDisplayText(view_->GetText())); | 1188 InternalSetUserText(UserTextFromDisplayText(view_->GetText())); |
1194 has_temporary_text_ = false; | 1189 has_temporary_text_ = false; |
1195 is_temporary_text_set_by_instant_ = false; | 1190 is_temporary_text_set_by_instant_ = false; |
1196 OnPopupBoundsChanged(gfx::Rect()); | 1191 OnPopupBoundsChanged(gfx::Rect()); |
1197 delegate_->NotifySearchTabHelper(user_input_in_progress_, !in_revert_); | 1192 delegate_->NotifySearchTabHelper(user_input_in_progress_, !in_revert_); |
1198 } | 1193 } |
1199 } | 1194 } |
1200 | 1195 |
1201 bool OmniboxEditModel::query_in_progress() const { | 1196 bool OmniboxEditModel::query_in_progress() const { |
1202 return !autocomplete_controller_->done(); | 1197 return !autocomplete_controller()->done(); |
1203 } | 1198 } |
1204 | 1199 |
1205 void OmniboxEditModel::InternalSetUserText(const string16& text) { | 1200 void OmniboxEditModel::InternalSetUserText(const string16& text) { |
1206 user_text_ = text; | 1201 user_text_ = text; |
1207 just_deleted_text_ = false; | 1202 just_deleted_text_ = false; |
1208 inline_autocomplete_text_.clear(); | 1203 inline_autocomplete_text_.clear(); |
1209 } | 1204 } |
1210 | 1205 |
1211 bool OmniboxEditModel::KeywordIsSelected() const { | 1206 bool OmniboxEditModel::KeywordIsSelected() const { |
1212 return !is_keyword_hint_ && !keyword_.empty(); | 1207 return !is_keyword_hint_ && !keyword_.empty(); |
(...skipping 11 matching lines...) Expand all Loading... |
1224 } | 1219 } |
1225 | 1220 |
1226 string16 OmniboxEditModel::UserTextFromDisplayText(const string16& text) const { | 1221 string16 OmniboxEditModel::UserTextFromDisplayText(const string16& text) const { |
1227 return KeywordIsSelected() ? (keyword_ + char16(' ') + text) : text; | 1222 return KeywordIsSelected() ? (keyword_ + char16(' ') + text) : text; |
1228 } | 1223 } |
1229 | 1224 |
1230 void OmniboxEditModel::InfoForCurrentSelection(AutocompleteMatch* match, | 1225 void OmniboxEditModel::InfoForCurrentSelection(AutocompleteMatch* match, |
1231 GURL* alternate_nav_url) const { | 1226 GURL* alternate_nav_url) const { |
1232 DCHECK(match != NULL); | 1227 DCHECK(match != NULL); |
1233 const AutocompleteResult& result = this->result(); | 1228 const AutocompleteResult& result = this->result(); |
1234 if (!autocomplete_controller_->done()) { | 1229 if (!autocomplete_controller()->done()) { |
1235 // It's technically possible for |result| to be empty if no provider returns | 1230 // It's technically possible for |result| to be empty if no provider returns |
1236 // a synchronous result but the query has not completed synchronously; | 1231 // a synchronous result but the query has not completed synchronously; |
1237 // pratically, however, that should never actually happen. | 1232 // pratically, however, that should never actually happen. |
1238 if (result.empty()) | 1233 if (result.empty()) |
1239 return; | 1234 return; |
1240 // The user cannot have manually selected a match, or the query would have | 1235 // The user cannot have manually selected a match, or the query would have |
1241 // stopped. So the default match must be the desired selection. | 1236 // stopped. So the default match must be the desired selection. |
1242 *match = *result.default_match(); | 1237 *match = *result.default_match(); |
1243 } else { | 1238 } else { |
1244 CHECK(popup_->IsOpen()); | 1239 CHECK(popup_->IsOpen()); |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1328 old_text, space_position, | 1323 old_text, space_position, |
1329 old_text.length() - space_position)) { | 1324 old_text.length() - space_position)) { |
1330 return false; | 1325 return false; |
1331 } | 1326 } |
1332 | 1327 |
1333 // Then check if the text before the inserted space matches a keyword. | 1328 // Then check if the text before the inserted space matches a keyword. |
1334 string16 keyword; | 1329 string16 keyword; |
1335 TrimWhitespace(new_text.substr(0, space_position), TRIM_LEADING, &keyword); | 1330 TrimWhitespace(new_text.substr(0, space_position), TRIM_LEADING, &keyword); |
1336 // TODO(sreeram): Once the Instant extended API supports keywords properly, | 1331 // TODO(sreeram): Once the Instant extended API supports keywords properly, |
1337 // keyword_provider() should never be NULL. Remove that clause. | 1332 // keyword_provider() should never be NULL. Remove that clause. |
1338 return !keyword.empty() && autocomplete_controller_->keyword_provider() && | 1333 return !keyword.empty() && autocomplete_controller()->keyword_provider() && |
1339 !autocomplete_controller_->keyword_provider()-> | 1334 !autocomplete_controller()->keyword_provider()-> |
1340 GetKeywordForText(keyword).empty(); | 1335 GetKeywordForText(keyword).empty(); |
1341 } | 1336 } |
1342 | 1337 |
1343 bool OmniboxEditModel::DoInstant(const AutocompleteMatch& match) { | 1338 bool OmniboxEditModel::DoInstant(const AutocompleteMatch& match) { |
1344 InstantController* instant = controller_->GetInstant(); | 1339 InstantController* instant = controller_->GetInstant(); |
1345 if (!instant || in_revert_) | 1340 if (!instant || in_revert_) |
1346 return false; | 1341 return false; |
1347 | 1342 |
1348 // Don't call Update() if the change is a result of a | 1343 // Don't call Update() if the change is a result of a |
1349 // INSTANT_COMPLETE_REPLACE instant suggestion. | 1344 // INSTANT_COMPLETE_REPLACE instant suggestion. |
1350 if (has_temporary_text_ && is_temporary_text_set_by_instant_) | 1345 if (has_temporary_text_ && is_temporary_text_set_by_instant_) |
1351 return false; | 1346 return false; |
1352 | 1347 |
1353 // The two pieces of text we want to send Instant, viz., what the user has | 1348 // The two pieces of text we want to send Instant, viz., what the user has |
1354 // typed, and the full omnibox text including any inline autocompletion. | 1349 // typed, and the full omnibox text including any inline autocompletion. |
1355 string16 user_text = has_temporary_text_ ? | 1350 string16 user_text = has_temporary_text_ ? |
1356 match.fill_into_edit : DisplayTextFromUserText(user_text_); | 1351 match.fill_into_edit : DisplayTextFromUserText(user_text_); |
1357 string16 full_text = view_->GetText(); | 1352 string16 full_text = view_->GetText(); |
1358 | 1353 |
1359 // Remove "?" if we're in forced query mode. | 1354 // Remove "?" if we're in forced query mode. |
1360 AutocompleteInput::RemoveForcedQueryStringIfNecessary( | 1355 AutocompleteInput::RemoveForcedQueryStringIfNecessary( |
1361 autocomplete_controller_->input().type(), &user_text); | 1356 autocomplete_controller()->input().type(), &user_text); |
1362 AutocompleteInput::RemoveForcedQueryStringIfNecessary( | 1357 AutocompleteInput::RemoveForcedQueryStringIfNecessary( |
1363 autocomplete_controller_->input().type(), &full_text); | 1358 autocomplete_controller()->input().type(), &full_text); |
1364 | 1359 |
1365 size_t start, end; | 1360 size_t start, end; |
1366 view_->GetSelectionBounds(&start, &end); | 1361 view_->GetSelectionBounds(&start, &end); |
1367 | 1362 |
1368 return instant->Update(match, user_text, full_text, start, end, | 1363 return instant->Update(match, user_text, full_text, start, end, |
1369 UseVerbatimInstant(), user_input_in_progress_, popup_->IsOpen(), | 1364 UseVerbatimInstant(), user_input_in_progress_, popup_->IsOpen(), |
1370 in_escape_handler_, KeywordIsSelected()); | 1365 in_escape_handler_, KeywordIsSelected()); |
1371 } | 1366 } |
1372 | 1367 |
1373 void OmniboxEditModel::DoPreconnect(const AutocompleteMatch& match) { | 1368 void OmniboxEditModel::DoPreconnect(const AutocompleteMatch& match) { |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1430 instant->OmniboxFocusChanged(state, reason, NULL); | 1425 instant->OmniboxFocusChanged(state, reason, NULL); |
1431 | 1426 |
1432 // Update state and notify view if the omnibox has focus and the caret | 1427 // Update state and notify view if the omnibox has focus and the caret |
1433 // visibility changed. | 1428 // visibility changed. |
1434 const bool was_caret_visible = is_caret_visible(); | 1429 const bool was_caret_visible = is_caret_visible(); |
1435 focus_state_ = state; | 1430 focus_state_ = state; |
1436 if (focus_state_ != OMNIBOX_FOCUS_NONE && | 1431 if (focus_state_ != OMNIBOX_FOCUS_NONE && |
1437 is_caret_visible() != was_caret_visible) | 1432 is_caret_visible() != was_caret_visible) |
1438 view_->ApplyCaretVisibility(); | 1433 view_->ApplyCaretVisibility(); |
1439 } | 1434 } |
OLD | NEW |