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/instant/instant_controller.h" | 5 #include "chrome/browser/instant/instant_controller.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/metrics/histogram.h" | 8 #include "base/metrics/histogram.h" |
9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
10 #include "base/utf_string_conversions.h" | 10 #include "base/utf_string_conversions.h" |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
149 InstantController::InstantController(chrome::BrowserInstantController* browser, | 149 InstantController::InstantController(chrome::BrowserInstantController* browser, |
150 bool extended_enabled) | 150 bool extended_enabled) |
151 : browser_(browser), | 151 : browser_(browser), |
152 extended_enabled_(extended_enabled), | 152 extended_enabled_(extended_enabled), |
153 instant_enabled_(false), | 153 instant_enabled_(false), |
154 model_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 154 model_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
155 last_omnibox_text_has_inline_autocompletion_(false), | 155 last_omnibox_text_has_inline_autocompletion_(false), |
156 last_verbatim_(false), | 156 last_verbatim_(false), |
157 last_transition_type_(content::PAGE_TRANSITION_LINK), | 157 last_transition_type_(content::PAGE_TRANSITION_LINK), |
158 last_match_was_search_(false), | 158 last_match_was_search_(false), |
159 is_omnibox_focused_(false), | 159 omnibox_focus_state_(OMNIBOX_FOCUS_NONE), |
160 allow_preview_to_show_search_suggestions_(false) { | 160 allow_preview_to_show_search_suggestions_(false) { |
161 } | 161 } |
162 | 162 |
163 InstantController::~InstantController() { | 163 InstantController::~InstantController() { |
164 } | 164 } |
165 | 165 |
166 bool InstantController::Update(const AutocompleteMatch& match, | 166 bool InstantController::Update(const AutocompleteMatch& match, |
167 const string16& user_text, | 167 const string16& user_text, |
168 const string16& full_text, | 168 const string16& full_text, |
169 size_t selection_start, | 169 size_t selection_start, |
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
540 // Delay deletion as we could've gotten here from an InstantLoader method. | 540 // Delay deletion as we could've gotten here from an InstantLoader method. |
541 MessageLoop::current()->DeleteSoon(FROM_HERE, loader_.release()); | 541 MessageLoop::current()->DeleteSoon(FROM_HERE, loader_.release()); |
542 | 542 |
543 // Try to create another loader immediately so that it is ready for the next | 543 // Try to create another loader immediately so that it is ready for the next |
544 // user interaction. | 544 // user interaction. |
545 CreateDefaultLoader(); | 545 CreateDefaultLoader(); |
546 | 546 |
547 return true; | 547 return true; |
548 } | 548 } |
549 | 549 |
550 void InstantController::OmniboxLostFocus(gfx::NativeView view_gaining_focus) { | 550 void InstantController::OmniboxFocusChanged( |
551 DVLOG(1) << "OmniboxLostFocus"; | 551 OmniboxFocusState state, |
552 is_omnibox_focused_ = false; | 552 OmniboxFocusChangeReason reason, |
| 553 gfx::NativeView view_gaining_focus) { |
| 554 DVLOG(1) << "OmniboxFocusChanged: " << omnibox_focus_state_ << " to " |
| 555 << state << " for reason " << reason; |
553 | 556 |
| 557 OmniboxFocusState old_focus_state = omnibox_focus_state_; |
| 558 omnibox_focus_state_ = state; |
554 if (!extended_enabled_ && !instant_enabled_) | 559 if (!extended_enabled_ && !instant_enabled_) |
555 return; | 560 return; |
556 | 561 |
557 // If the preview is showing custom NTP content, don't hide it, commit it | 562 // Tell the page if the key capture mode changed unless the focus state |
558 // (no matter where the user clicked) or try to recreate it. | 563 // changed because of TYPING. This is because in that case, the browser hasn't |
559 if (model_.mode().is_ntp()) | 564 // really stopped capturing key strokes. |
560 return; | 565 // |
| 566 // (More practically, if we don't do this check, the page would receive |
| 567 // onkeycapturechange before the corresponding onchange, and the page would |
| 568 // have no way of telling whether the keycapturechange happened because of |
| 569 // some actual user action or just because they started typing.) |
| 570 if (extended_enabled_ && GetPreviewContents() && |
| 571 reason != OMNIBOX_FOCUS_CHANGE_TYPING) |
| 572 loader_->KeyCaptureChanged(omnibox_focus_state_ == OMNIBOX_FOCUS_INVISIBLE); |
561 | 573 |
562 // If the preview is not showing at all, recreate it if it's stale. | 574 // If focus went from outside the omnibox to the omnibox, preload the default |
563 if (model_.mode().is_default()) { | 575 // search engine, in anticipation of the user typing a query. If the reverse |
564 OnStaleLoader(); | 576 // happened, commit or discard the preview. |
565 return; | 577 if (state != OMNIBOX_FOCUS_NONE && old_focus_state == OMNIBOX_FOCUS_NONE) |
566 } | 578 CreateDefaultLoader(); |
567 | 579 else if (state == OMNIBOX_FOCUS_NONE && old_focus_state != OMNIBOX_FOCUS_NONE) |
568 // The preview is showing search suggestions. If GetPreviewContents() is NULL, | 580 OmniboxLostFocus(view_gaining_focus); |
569 // we are in the commit path. Don't do anything. | |
570 if (!GetPreviewContents()) | |
571 return; | |
572 | |
573 #if defined(OS_MACOSX) | |
574 // TODO(sreeram): See if Mac really needs this special treatment. | |
575 if (!loader_->is_pointer_down_from_activate()) | |
576 HideLoader(); | |
577 #else | |
578 if (IsViewInContents(GetViewGainingFocus(view_gaining_focus), | |
579 loader_->contents())) | |
580 CommitIfPossible(INSTANT_COMMIT_FOCUS_LOST); | |
581 else | |
582 HideLoader(); | |
583 #endif | |
584 } | |
585 | |
586 void InstantController::OmniboxGotFocus() { | |
587 DVLOG(1) << "OmniboxGotFocus"; | |
588 is_omnibox_focused_ = true; | |
589 | |
590 if (!extended_enabled_ && !instant_enabled_) | |
591 return; | |
592 | |
593 CreateDefaultLoader(); | |
594 } | 581 } |
595 | 582 |
596 void InstantController::SearchModeChanged( | 583 void InstantController::SearchModeChanged( |
597 const chrome::search::Mode& old_mode, | 584 const chrome::search::Mode& old_mode, |
598 const chrome::search::Mode& new_mode) { | 585 const chrome::search::Mode& new_mode) { |
599 if (!extended_enabled_) | 586 if (!extended_enabled_) |
600 return; | 587 return; |
601 | 588 |
602 DVLOG(1) << "SearchModeChanged: [origin:mode] " << old_mode.origin << ":" | 589 DVLOG(1) << "SearchModeChanged: [origin:mode] " << old_mode.origin << ":" |
603 << old_mode.mode << " to " << new_mode.origin << ":" | 590 << old_mode.mode << " to " << new_mode.origin << ":" |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
803 void InstantController::InstantLoaderAboutToNavigateMainFrame(const GURL& url) { | 790 void InstantController::InstantLoaderAboutToNavigateMainFrame(const GURL& url) { |
804 GURL instant_url(loader_->instant_url()); | 791 GURL instant_url(loader_->instant_url()); |
805 | 792 |
806 // Don't commit if the URL being navigated to has the same host and path as | 793 // Don't commit if the URL being navigated to has the same host and path as |
807 // the instant URL. This enables the instant page to change the query | 794 // the instant URL. This enables the instant page to change the query |
808 // parameters and fragments of the URL without it navigating. | 795 // parameters and fragments of the URL without it navigating. |
809 if (url.host() != instant_url.host() || url.path() != instant_url.path()) | 796 if (url.host() != instant_url.host() || url.path() != instant_url.path()) |
810 CommitIfPossible(INSTANT_COMMIT_NAVIGATED); | 797 CommitIfPossible(INSTANT_COMMIT_NAVIGATED); |
811 } | 798 } |
812 | 799 |
| 800 void InstantController::OmniboxLostFocus(gfx::NativeView view_gaining_focus) { |
| 801 // If the preview is showing custom NTP content, don't hide it, commit it |
| 802 // (no matter where the user clicked) or try to recreate it. |
| 803 if (model_.mode().is_ntp()) |
| 804 return; |
| 805 |
| 806 // If the preview is not showing at all, recreate it if it's stale. |
| 807 if (model_.mode().is_default()) { |
| 808 OnStaleLoader(); |
| 809 return; |
| 810 } |
| 811 |
| 812 // The preview is showing search suggestions. If GetPreviewContents() is NULL, |
| 813 // we are in the commit path. Don't do anything. |
| 814 if (!GetPreviewContents()) |
| 815 return; |
| 816 |
| 817 #if defined(OS_MACOSX) |
| 818 // TODO(sreeram): See if Mac really needs this special treatment. |
| 819 if (!loader_->is_pointer_down_from_activate()) |
| 820 HideLoader(); |
| 821 #else |
| 822 if (IsViewInContents(GetViewGainingFocus(view_gaining_focus), |
| 823 loader_->contents())) |
| 824 CommitIfPossible(INSTANT_COMMIT_FOCUS_LOST); |
| 825 else |
| 826 HideLoader(); |
| 827 #endif |
| 828 } |
| 829 |
813 bool InstantController::ResetLoader(const TemplateURL* template_url, | 830 bool InstantController::ResetLoader(const TemplateURL* template_url, |
814 const content::WebContents* active_tab) { | 831 const content::WebContents* active_tab) { |
815 std::string instant_url; | 832 std::string instant_url; |
816 if (!GetInstantURL(template_url, &instant_url)) | 833 if (!GetInstantURL(template_url, &instant_url)) |
817 return false; | 834 return false; |
818 | 835 |
819 if (loader_ && loader_->instant_url() == instant_url) | 836 if (loader_ && loader_->instant_url() == instant_url) |
820 return true; | 837 return true; |
821 | 838 |
822 HideInternal(); | 839 HideInternal(); |
823 loader_.reset(new InstantLoader(this, instant_url)); | 840 loader_.reset(new InstantLoader(this, instant_url)); |
824 loader_->InitContents(active_tab); | 841 loader_->InitContents(active_tab); |
825 | 842 |
826 // Ensure the searchbox API has the correct initial state. | 843 // Ensure the searchbox API has the correct initial state. |
827 if (extended_enabled_) { | 844 if (extended_enabled_) { |
828 browser_->UpdateThemeInfoForPreview(); | 845 browser_->UpdateThemeInfoForPreview(); |
829 loader_->SetDisplayInstantResults(instant_enabled_); | 846 loader_->SetDisplayInstantResults(instant_enabled_); |
830 loader_->SearchModeChanged(search_mode_); | 847 loader_->SearchModeChanged(search_mode_); |
| 848 loader_->KeyCaptureChanged(omnibox_focus_state_ == OMNIBOX_FOCUS_INVISIBLE); |
831 } | 849 } |
832 | 850 |
833 // Restart the stale loader timer. | 851 // Restart the stale loader timer. |
834 stale_loader_timer_.Start(FROM_HERE, | 852 stale_loader_timer_.Start(FROM_HERE, |
835 base::TimeDelta::FromMilliseconds(kStaleLoaderTimeoutMS), this, | 853 base::TimeDelta::FromMilliseconds(kStaleLoaderTimeoutMS), this, |
836 &InstantController::OnStaleLoader); | 854 &InstantController::OnStaleLoader); |
837 | 855 |
838 return true; | 856 return true; |
839 } | 857 } |
840 | 858 |
841 bool InstantController::CreateDefaultLoader() { | 859 bool InstantController::CreateDefaultLoader() { |
842 // If there's no active tab, the browser is closing. | 860 // If there's no active tab, the browser is closing. |
843 const content::WebContents* active_tab = browser_->GetActiveWebContents(); | 861 const content::WebContents* active_tab = browser_->GetActiveWebContents(); |
844 if (!active_tab) | 862 if (!active_tab) |
845 return false; | 863 return false; |
846 | 864 |
847 const TemplateURL* template_url = TemplateURLServiceFactory::GetForProfile( | 865 const TemplateURL* template_url = TemplateURLServiceFactory::GetForProfile( |
848 Profile::FromBrowserContext(active_tab->GetBrowserContext()))-> | 866 Profile::FromBrowserContext(active_tab->GetBrowserContext()))-> |
849 GetDefaultSearchProvider(); | 867 GetDefaultSearchProvider(); |
850 | 868 |
851 return ResetLoader(template_url, active_tab); | 869 return ResetLoader(template_url, active_tab); |
852 } | 870 } |
853 | 871 |
854 void InstantController::OnStaleLoader() { | 872 void InstantController::OnStaleLoader() { |
855 // If the preview is showing or the omnibox has focus, don't delete the | 873 // If the preview is showing or the omnibox has focus, don't delete the |
856 // loader. It will get refreshed the next time the preview is hidden or the | 874 // loader. It will get refreshed the next time the preview is hidden or the |
857 // omnibox loses focus. | 875 // omnibox loses focus. |
858 if (!stale_loader_timer_.IsRunning() && !is_omnibox_focused_ && | 876 if (!stale_loader_timer_.IsRunning() && |
| 877 omnibox_focus_state_ == OMNIBOX_FOCUS_NONE && |
859 model_.mode().is_default()) { | 878 model_.mode().is_default()) { |
860 loader_.reset(); | 879 loader_.reset(); |
861 CreateDefaultLoader(); | 880 CreateDefaultLoader(); |
862 } | 881 } |
863 } | 882 } |
864 | 883 |
865 void InstantController::ResetInstantTab() { | 884 void InstantController::ResetInstantTab() { |
866 if (search_mode_.is_origin_search()) { | 885 if (search_mode_.is_origin_search()) { |
867 content::WebContents* active_tab = browser_->GetActiveWebContents(); | 886 content::WebContents* active_tab = browser_->GetActiveWebContents(); |
868 if (!instant_tab_ || active_tab != instant_tab_->contents()) { | 887 if (!instant_tab_ || active_tab != instant_tab_->contents()) { |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1048 } | 1067 } |
1049 | 1068 |
1050 std::map<std::string, int>::const_iterator iter = | 1069 std::map<std::string, int>::const_iterator iter = |
1051 blacklisted_urls_.find(*instant_url); | 1070 blacklisted_urls_.find(*instant_url); |
1052 if (iter != blacklisted_urls_.end() && | 1071 if (iter != blacklisted_urls_.end() && |
1053 iter->second > kMaxInstantSupportFailures) | 1072 iter->second > kMaxInstantSupportFailures) |
1054 return false; | 1073 return false; |
1055 | 1074 |
1056 return true; | 1075 return true; |
1057 } | 1076 } |
OLD | NEW |