| 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 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 | 140 |
| 141 return false; | 141 return false; |
| 142 } | 142 } |
| 143 | 143 |
| 144 bool IsFullHeight(const InstantModel& model) { | 144 bool IsFullHeight(const InstantModel& model) { |
| 145 return model.height() == 100 && model.height_units() == INSTANT_SIZE_PERCENT; | 145 return model.height() == 100 && model.height_units() == INSTANT_SIZE_PERCENT; |
| 146 } | 146 } |
| 147 | 147 |
| 148 } // namespace | 148 } // namespace |
| 149 | 149 |
| 150 // static |
| 151 const char* InstantController::kLocalOmniboxPopupURL = |
| 152 "chrome://local-omnibox-popup/local-omnibox-popup.html"; |
| 153 |
| 150 InstantController::InstantController(chrome::BrowserInstantController* browser, | 154 InstantController::InstantController(chrome::BrowserInstantController* browser, |
| 151 bool extended_enabled) | 155 bool extended_enabled, |
| 156 bool use_local_preview_only) |
| 152 : browser_(browser), | 157 : browser_(browser), |
| 153 extended_enabled_(extended_enabled), | 158 extended_enabled_(extended_enabled), |
| 154 instant_enabled_(false), | 159 instant_enabled_(false), |
| 160 use_local_preview_only_(use_local_preview_only), |
| 155 model_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 161 model_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
| 156 last_omnibox_text_has_inline_autocompletion_(false), | 162 last_omnibox_text_has_inline_autocompletion_(false), |
| 157 last_verbatim_(false), | 163 last_verbatim_(false), |
| 158 last_transition_type_(content::PAGE_TRANSITION_LINK), | 164 last_transition_type_(content::PAGE_TRANSITION_LINK), |
| 159 last_match_was_search_(false), | 165 last_match_was_search_(false), |
| 160 omnibox_focus_state_(OMNIBOX_FOCUS_NONE), | 166 omnibox_focus_state_(OMNIBOX_FOCUS_NONE), |
| 161 start_margin_(0), | 167 start_margin_(0), |
| 162 end_margin_(0), | 168 end_margin_(0), |
| 163 allow_preview_to_show_search_suggestions_(false) { | 169 allow_preview_to_show_search_suggestions_(false) { |
| 164 } | 170 } |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 403 match != (*provider)->matches().end(); ++match) { | 409 match != (*provider)->matches().end(); ++match) { |
| 404 InstantAutocompleteResult result; | 410 InstantAutocompleteResult result; |
| 405 result.provider = UTF8ToUTF16((*provider)->GetName()); | 411 result.provider = UTF8ToUTF16((*provider)->GetName()); |
| 406 result.type = UTF8ToUTF16(AutocompleteMatch::TypeToString(match->type)); | 412 result.type = UTF8ToUTF16(AutocompleteMatch::TypeToString(match->type)); |
| 407 result.description = match->description; | 413 result.description = match->description; |
| 408 result.destination_url = UTF8ToUTF16(match->destination_url.spec()); | 414 result.destination_url = UTF8ToUTF16(match->destination_url.spec()); |
| 409 result.transition = match->transition; | 415 result.transition = match->transition; |
| 410 result.relevance = match->relevance; | 416 result.relevance = match->relevance; |
| 411 DVLOG(1) << " " << result.relevance << " " << result.type << " " | 417 DVLOG(1) << " " << result.relevance << " " << result.type << " " |
| 412 << result.provider << " " << result.destination_url << " '" | 418 << result.provider << " " << result.destination_url << " '" |
| 413 << result.description << "'"; | 419 << result.description << "' " << result.transition; |
| 414 results.push_back(result); | 420 results.push_back(result); |
| 415 } | 421 } |
| 416 } | 422 } |
| 417 | 423 |
| 418 if (instant_tab_) | 424 if (instant_tab_) |
| 419 instant_tab_->SendAutocompleteResults(results); | 425 instant_tab_->SendAutocompleteResults(results); |
| 420 else | 426 else |
| 421 loader_->SendAutocompleteResults(results); | 427 loader_->SendAutocompleteResults(results); |
| 422 } | 428 } |
| 423 | 429 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 460 instant_tab_->Submit(last_omnibox_text_); | 466 instant_tab_->Submit(last_omnibox_text_); |
| 461 instant_tab_->contents()->Focus(); | 467 instant_tab_->contents()->Focus(); |
| 462 return true; | 468 return true; |
| 463 } | 469 } |
| 464 return false; | 470 return false; |
| 465 } | 471 } |
| 466 | 472 |
| 467 if (!IsPreviewingSearchResults() && type != INSTANT_COMMIT_NAVIGATED) | 473 if (!IsPreviewingSearchResults() && type != INSTANT_COMMIT_NAVIGATED) |
| 468 return false; | 474 return false; |
| 469 | 475 |
| 476 // Never commit the local omnibox. |
| 477 if (loader_->IsUsingLocalPreview()) |
| 478 return false; |
| 479 |
| 470 if (type == INSTANT_COMMIT_FOCUS_LOST) | 480 if (type == INSTANT_COMMIT_FOCUS_LOST) |
| 471 loader_->Cancel(last_omnibox_text_); | 481 loader_->Cancel(last_omnibox_text_); |
| 472 else if (type != INSTANT_COMMIT_NAVIGATED && | 482 else if (type != INSTANT_COMMIT_NAVIGATED && |
| 473 type != INSTANT_COMMIT_CLICKED_QUERY_SUGGESTION) | 483 type != INSTANT_COMMIT_CLICKED_QUERY_SUGGESTION) |
| 474 loader_->Submit(last_omnibox_text_); | 484 loader_->Submit(last_omnibox_text_); |
| 475 | 485 |
| 476 content::WebContents* preview = loader_->ReleaseContents(); | 486 content::WebContents* preview = loader_->ReleaseContents(); |
| 477 | 487 |
| 478 if (extended_enabled_) { | 488 if (extended_enabled_) { |
| 479 // Consider what's happening: | 489 // Consider what's happening: |
| (...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 874 void InstantController::NavigateToURL(const GURL& url, | 884 void InstantController::NavigateToURL(const GURL& url, |
| 875 content::PageTransition transition) { | 885 content::PageTransition transition) { |
| 876 if (!extended_enabled_) | 886 if (!extended_enabled_) |
| 877 return; | 887 return; |
| 878 if (loader_) | 888 if (loader_) |
| 879 HideLoader(); | 889 HideLoader(); |
| 880 browser_->OpenURLInCurrentTab(url, transition); | 890 browser_->OpenURLInCurrentTab(url, transition); |
| 881 } | 891 } |
| 882 | 892 |
| 883 bool InstantController::ResetLoader(const TemplateURL* template_url, | 893 bool InstantController::ResetLoader(const TemplateURL* template_url, |
| 884 const content::WebContents* active_tab) { | 894 const content::WebContents* active_tab, |
| 895 bool fallback_to_local) { |
| 885 std::string instant_url; | 896 std::string instant_url; |
| 886 if (!GetInstantURL(template_url, &instant_url)) | 897 if (!GetInstantURL(template_url, &instant_url)) { |
| 887 return false; | 898 if (!fallback_to_local || !extended_enabled_) |
| 899 return false; |
| 900 |
| 901 // If we are in extended mode, fallback to the local popup. |
| 902 instant_url = kLocalOmniboxPopupURL; |
| 903 } |
| 888 | 904 |
| 889 if (loader_ && loader_->instant_url() == instant_url) | 905 if (loader_ && loader_->instant_url() == instant_url) |
| 890 return true; | 906 return true; |
| 891 | 907 |
| 892 HideInternal(); | 908 HideInternal(); |
| 893 loader_.reset(new InstantLoader(this, instant_url)); | 909 loader_.reset(new InstantLoader(this, instant_url)); |
| 894 loader_->InitContents(active_tab); | 910 loader_->InitContents(active_tab); |
| 895 | 911 |
| 896 // Ensure the searchbox API has the correct initial state. | 912 // Ensure the searchbox API has the correct initial state. |
| 897 if (extended_enabled_) { | 913 if (extended_enabled_) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 913 bool InstantController::CreateDefaultLoader() { | 929 bool InstantController::CreateDefaultLoader() { |
| 914 // If there's no active tab, the browser is closing. | 930 // If there's no active tab, the browser is closing. |
| 915 const content::WebContents* active_tab = browser_->GetActiveWebContents(); | 931 const content::WebContents* active_tab = browser_->GetActiveWebContents(); |
| 916 if (!active_tab) | 932 if (!active_tab) |
| 917 return false; | 933 return false; |
| 918 | 934 |
| 919 const TemplateURL* template_url = TemplateURLServiceFactory::GetForProfile( | 935 const TemplateURL* template_url = TemplateURLServiceFactory::GetForProfile( |
| 920 Profile::FromBrowserContext(active_tab->GetBrowserContext()))-> | 936 Profile::FromBrowserContext(active_tab->GetBrowserContext()))-> |
| 921 GetDefaultSearchProvider(); | 937 GetDefaultSearchProvider(); |
| 922 | 938 |
| 923 return ResetLoader(template_url, active_tab); | 939 return ResetLoader(template_url, active_tab, true); |
| 924 } | 940 } |
| 925 | 941 |
| 926 void InstantController::OnStaleLoader() { | 942 void InstantController::OnStaleLoader() { |
| 943 // The local popup is never stale. |
| 944 if (loader_ && loader_->IsUsingLocalPreview()) |
| 945 return; |
| 946 |
| 927 // If the preview is showing or the omnibox has focus, don't delete the | 947 // If the preview is showing or the omnibox has focus, don't delete the |
| 928 // loader. It will get refreshed the next time the preview is hidden or the | 948 // loader. It will get refreshed the next time the preview is hidden or the |
| 929 // omnibox loses focus. | 949 // omnibox loses focus. |
| 930 if (!stale_loader_timer_.IsRunning() && | 950 if (!stale_loader_timer_.IsRunning() && |
| 931 omnibox_focus_state_ == OMNIBOX_FOCUS_NONE && | 951 omnibox_focus_state_ == OMNIBOX_FOCUS_NONE && |
| 932 model_.mode().is_default()) { | 952 model_.mode().is_default()) { |
| 933 loader_.reset(); | 953 loader_.reset(); |
| 934 CreateDefaultLoader(); | 954 CreateDefaultLoader(); |
| 935 } | 955 } |
| 936 } | 956 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 958 // of |match|, we shouldn't use the committed tab. | 978 // of |match|, we shouldn't use the committed tab. |
| 959 if (instant_tab_) | 979 if (instant_tab_) |
| 960 return true; | 980 return true; |
| 961 | 981 |
| 962 // If there's no active tab, the browser is closing. | 982 // If there's no active tab, the browser is closing. |
| 963 const content::WebContents* active_tab = browser_->GetActiveWebContents(); | 983 const content::WebContents* active_tab = browser_->GetActiveWebContents(); |
| 964 if (!active_tab) | 984 if (!active_tab) |
| 965 return false; | 985 return false; |
| 966 | 986 |
| 967 // Try to create a loader for the instant_url in the TemplateURL of |match|. | 987 // Try to create a loader for the instant_url in the TemplateURL of |match|. |
| 988 // Do not fallback to the local preview because if the keyword specific |
| 989 // instant URL fails, we want to first try the default instant URL which |
| 990 // happens in the CreateDefaultLoader call below. |
| 968 const TemplateURL* template_url = match.GetTemplateURL( | 991 const TemplateURL* template_url = match.GetTemplateURL( |
| 969 Profile::FromBrowserContext(active_tab->GetBrowserContext()), false); | 992 Profile::FromBrowserContext(active_tab->GetBrowserContext()), false); |
| 970 if (ResetLoader(template_url, active_tab)) | 993 if (ResetLoader(template_url, active_tab, false)) |
| 971 return true; | 994 return true; |
| 972 | 995 |
| 973 // In non-extended mode, stop if we couldn't get a loader for the |match|. | 996 // In non-extended mode, stop if we couldn't get a loader for the |match|. |
| 974 if (!extended_enabled_) | 997 if (!extended_enabled_) |
| 975 return false; | 998 return false; |
| 976 | 999 |
| 977 // If the match is a query, it is for a non-Instant search engine; stop. | 1000 // If the match is a query, it is for a non-Instant search engine; stop. |
| 978 if (last_match_was_search_) | 1001 if (last_match_was_search_) |
| 979 return false; | 1002 return false; |
| 980 | 1003 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1034 } | 1057 } |
| 1035 | 1058 |
| 1036 // If the preview is being shown for the first time since the user started | 1059 // If the preview is being shown for the first time since the user started |
| 1037 // typing, record a histogram value. | 1060 // typing, record a histogram value. |
| 1038 if (!first_interaction_time_.is_null() && model_.mode().is_default()) { | 1061 if (!first_interaction_time_.is_null() && model_.mode().is_default()) { |
| 1039 base::TimeDelta delta = base::Time::Now() - first_interaction_time_; | 1062 base::TimeDelta delta = base::Time::Now() - first_interaction_time_; |
| 1040 UMA_HISTOGRAM_TIMES("Instant.TimeToFirstShow", delta); | 1063 UMA_HISTOGRAM_TIMES("Instant.TimeToFirstShow", delta); |
| 1041 } | 1064 } |
| 1042 | 1065 |
| 1043 // Show at 100% height except in the following cases: | 1066 // Show at 100% height except in the following cases: |
| 1067 // - The local omnibox popup is being loaded. |
| 1044 // - Instant is disabled. The page needs to be able to show only a dropdown. | 1068 // - Instant is disabled. The page needs to be able to show only a dropdown. |
| 1045 // - The page wants to show custom NTP content. | 1069 // - The page wants to show custom NTP content. |
| 1046 // - The page is over a website other than search or an NTP, and is not | 1070 // - The page is over a website other than search or an NTP, and is not |
| 1047 // already showing at 100% height. | 1071 // already showing at 100% height. |
| 1048 if (!instant_enabled_ || reason == INSTANT_SHOWN_CUSTOM_NTP_CONTENT || | 1072 if (loader_->IsUsingLocalPreview() || !instant_enabled_ || |
| 1073 reason == INSTANT_SHOWN_CUSTOM_NTP_CONTENT || |
| 1049 (search_mode_.is_origin_default() && !IsFullHeight(model_))) | 1074 (search_mode_.is_origin_default() && !IsFullHeight(model_))) |
| 1050 model_.SetPreviewState(search_mode_, height, units); | 1075 model_.SetPreviewState(search_mode_, height, units); |
| 1051 else | 1076 else |
| 1052 model_.SetPreviewState(search_mode_, 100, INSTANT_SIZE_PERCENT); | 1077 model_.SetPreviewState(search_mode_, 100, INSTANT_SIZE_PERCENT); |
| 1053 | 1078 |
| 1054 // If the user clicked on a query suggestion, also go ahead and commit the | 1079 // If the user clicked on a query suggestion, also go ahead and commit the |
| 1055 // overlay. This is necessary because if the overlay was partially visible | 1080 // overlay. This is necessary because if the overlay was partially visible |
| 1056 // when the suggestion was clicked, the click itself would not commit the | 1081 // when the suggestion was clicked, the click itself would not commit the |
| 1057 // overlay (because we're not full height). | 1082 // overlay (because we're not full height). |
| 1058 if (reason == INSTANT_SHOWN_CLICKED_QUERY_SUGGESTION) | 1083 if (reason == INSTANT_SHOWN_CLICKED_QUERY_SUGGESTION) |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1081 // Mac fullscreen mode, the omnibox is fully enclosed by the preview bounds). | 1106 // Mac fullscreen mode, the omnibox is fully enclosed by the preview bounds). |
| 1082 DCHECK_LE(0, intersection.x()); | 1107 DCHECK_LE(0, intersection.x()); |
| 1083 DCHECK_LE(0, intersection.width()); | 1108 DCHECK_LE(0, intersection.width()); |
| 1084 DCHECK_LE(0, intersection.height()); | 1109 DCHECK_LE(0, intersection.height()); |
| 1085 | 1110 |
| 1086 loader_->SetPopupBounds(intersection); | 1111 loader_->SetPopupBounds(intersection); |
| 1087 } | 1112 } |
| 1088 | 1113 |
| 1089 bool InstantController::GetInstantURL(const TemplateURL* template_url, | 1114 bool InstantController::GetInstantURL(const TemplateURL* template_url, |
| 1090 std::string* instant_url) const { | 1115 std::string* instant_url) const { |
| 1116 if (extended_enabled_ && use_local_preview_only_) { |
| 1117 *instant_url = kLocalOmniboxPopupURL; |
| 1118 return true; |
| 1119 } |
| 1120 |
| 1091 CommandLine* command_line = CommandLine::ForCurrentProcess(); | 1121 CommandLine* command_line = CommandLine::ForCurrentProcess(); |
| 1092 if (command_line->HasSwitch(switches::kInstantURL)) { | 1122 if (command_line->HasSwitch(switches::kInstantURL)) { |
| 1093 *instant_url = command_line->GetSwitchValueASCII(switches::kInstantURL); | 1123 *instant_url = command_line->GetSwitchValueASCII(switches::kInstantURL); |
| 1094 return template_url != NULL; | 1124 return template_url != NULL; |
| 1095 } | 1125 } |
| 1096 | 1126 |
| 1097 if (!template_url) | 1127 if (!template_url) |
| 1098 return false; | 1128 return false; |
| 1099 | 1129 |
| 1100 const TemplateURLRef& instant_url_ref = template_url->instant_url_ref(); | 1130 const TemplateURLRef& instant_url_ref = template_url->instant_url_ref(); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1130 } | 1160 } |
| 1131 | 1161 |
| 1132 std::map<std::string, int>::const_iterator iter = | 1162 std::map<std::string, int>::const_iterator iter = |
| 1133 blacklisted_urls_.find(*instant_url); | 1163 blacklisted_urls_.find(*instant_url); |
| 1134 if (iter != blacklisted_urls_.end() && | 1164 if (iter != blacklisted_urls_.end() && |
| 1135 iter->second > kMaxInstantSupportFailures) | 1165 iter->second > kMaxInstantSupportFailures) |
| 1136 return false; | 1166 return false; |
| 1137 | 1167 |
| 1138 return true; | 1168 return true; |
| 1139 } | 1169 } |
| OLD | NEW |