| 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 |