Chromium Code Reviews| 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 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 173 instant_enabled_(false), | 173 instant_enabled_(false), |
| 174 use_local_preview_only_(use_local_preview_only), | 174 use_local_preview_only_(use_local_preview_only), |
| 175 model_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 175 model_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
| 176 last_omnibox_text_has_inline_autocompletion_(false), | 176 last_omnibox_text_has_inline_autocompletion_(false), |
| 177 last_verbatim_(false), | 177 last_verbatim_(false), |
| 178 last_transition_type_(content::PAGE_TRANSITION_LINK), | 178 last_transition_type_(content::PAGE_TRANSITION_LINK), |
| 179 last_match_was_search_(false), | 179 last_match_was_search_(false), |
| 180 omnibox_focus_state_(OMNIBOX_FOCUS_NONE), | 180 omnibox_focus_state_(OMNIBOX_FOCUS_NONE), |
| 181 start_margin_(0), | 181 start_margin_(0), |
| 182 end_margin_(0), | 182 end_margin_(0), |
| 183 allow_preview_to_show_search_suggestions_(false) { | 183 allow_preview_to_show_search_suggestions_(false), |
| 184 instant_set_transient_entry_(false) { | |
| 184 } | 185 } |
| 185 | 186 |
| 186 InstantController::~InstantController() { | 187 InstantController::~InstantController() { |
| 187 } | 188 } |
| 188 | 189 |
| 189 bool InstantController::Update(const AutocompleteMatch& match, | 190 bool InstantController::Update(const AutocompleteMatch& match, |
| 190 const string16& user_text, | 191 const string16& user_text, |
| 191 const string16& full_text, | 192 const string16& full_text, |
| 192 size_t selection_start, | 193 size_t selection_start, |
| 193 size_t selection_end, | 194 size_t selection_end, |
| (...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 682 // content, and the new tab is also an NTP. | 683 // content, and the new tab is also an NTP. |
| 683 if (!search_mode_.is_ntp() || !model_.mode().is_ntp()) | 684 if (!search_mode_.is_ntp() || !model_.mode().is_ntp()) |
| 684 HideLoader(); | 685 HideLoader(); |
| 685 | 686 |
| 686 if (extended_enabled_) | 687 if (extended_enabled_) |
| 687 ResetInstantTab(); | 688 ResetInstantTab(); |
| 688 } | 689 } |
| 689 | 690 |
| 690 void InstantController::TabDeactivated(content::WebContents* contents) { | 691 void InstantController::TabDeactivated(content::WebContents* contents) { |
| 691 DVLOG(1) << "TabDeactivated"; | 692 DVLOG(1) << "TabDeactivated"; |
| 692 if (extended_enabled_ && !contents->IsBeingDestroyed()) | 693 if (extended_enabled_) { |
| 693 CommitIfPossible(INSTANT_COMMIT_FOCUS_LOST); | 694 if (!contents->IsBeingDestroyed()) { |
| 695 CommitIfPossible(INSTANT_COMMIT_FOCUS_LOST); | |
| 696 } else { | |
| 697 // The tab is going away. Trying to restore its original transient entry | |
| 698 // would affect the wrong tab. | |
| 699 saved_transient_entry_.reset(); | |
|
sreeram
2013/01/25 21:28:02
Doesn't this break tab-restore? Quoting myself fro
| |
| 700 } | |
| 701 } | |
| 694 } | 702 } |
| 695 | 703 |
| 696 void InstantController::SetInstantEnabled(bool instant_enabled) { | 704 void InstantController::SetInstantEnabled(bool instant_enabled) { |
| 697 DVLOG(1) << "SetInstantEnabled: " << instant_enabled; | 705 DVLOG(1) << "SetInstantEnabled: " << instant_enabled; |
| 698 instant_enabled_ = instant_enabled; | 706 instant_enabled_ = instant_enabled; |
| 699 HideInternal(); | 707 HideInternal(); |
| 700 loader_.reset(); | 708 loader_.reset(); |
| 701 if (extended_enabled_ || instant_enabled_) | 709 if (extended_enabled_ || instant_enabled_) |
| 702 CreateDefaultLoader(); | 710 CreateDefaultLoader(); |
| 703 if (instant_tab_) | 711 if (instant_tab_) |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 902 | 910 |
| 903 // Commit the navigation if either: | 911 // Commit the navigation if either: |
| 904 // - The page is in NTP mode (so it could only navigate on a user click) or | 912 // - The page is in NTP mode (so it could only navigate on a user click) or |
| 905 // - The page is not in NTP mode and we are navigating to a URL with a | 913 // - The page is not in NTP mode and we are navigating to a URL with a |
| 906 // different host or path than the instant URL. This enables the instant | 914 // different host or path than the instant URL. This enables the instant |
| 907 // page when it is showing search results to change the query parameters | 915 // page when it is showing search results to change the query parameters |
| 908 // and fragments of the URL without it navigating. | 916 // and fragments of the URL without it navigating. |
| 909 if (model_.mode().is_ntp() || | 917 if (model_.mode().is_ntp() || |
| 910 (url.host() != instant_url.host() || url.path() != instant_url.path())) { | 918 (url.host() != instant_url.host() || url.path() != instant_url.path())) { |
| 911 CommitIfPossible(INSTANT_COMMIT_NAVIGATED); | 919 CommitIfPossible(INSTANT_COMMIT_NAVIGATED); |
| 920 } else { | |
| 921 UpdateTransientHistoryEntry(url); | |
| 912 } | 922 } |
| 913 } | 923 } |
| 914 | 924 |
| 915 void InstantController::OmniboxLostFocus(gfx::NativeView view_gaining_focus) { | 925 void InstantController::OmniboxLostFocus(gfx::NativeView view_gaining_focus) { |
| 916 // If the preview is showing custom NTP content, don't hide it, commit it | 926 // If the preview is showing custom NTP content, don't hide it, commit it |
| 917 // (no matter where the user clicked) or try to recreate it. | 927 // (no matter where the user clicked) or try to recreate it. |
| 918 if (model_.mode().is_ntp()) | 928 if (model_.mode().is_ntp()) |
| 919 return; | 929 return; |
| 920 | 930 |
| 921 // If the preview is not showing at all, recreate it if it's stale. | 931 // If the preview is not showing at all, recreate it if it's stale. |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1081 // change the state just yet; else we may hide the preview unnecessarily. | 1091 // change the state just yet; else we may hide the preview unnecessarily. |
| 1082 // Instead, the state will be set correctly after the commit is done. | 1092 // Instead, the state will be set correctly after the commit is done. |
| 1083 if (GetPreviewContents()) { | 1093 if (GetPreviewContents()) { |
| 1084 model_.SetPreviewState(chrome::search::Mode(), 0, INSTANT_SIZE_PERCENT); | 1094 model_.SetPreviewState(chrome::search::Mode(), 0, INSTANT_SIZE_PERCENT); |
| 1085 allow_preview_to_show_search_suggestions_ = false; | 1095 allow_preview_to_show_search_suggestions_ = false; |
| 1086 | 1096 |
| 1087 // Send a message asking the preview to clear out old results. | 1097 // Send a message asking the preview to clear out old results. |
| 1088 loader_->Update(string16(), 0, 0, true); | 1098 loader_->Update(string16(), 0, 0, true); |
| 1089 } | 1099 } |
| 1090 | 1100 |
| 1101 ResetTransientHistoryEntry(); | |
| 1102 | |
| 1091 // Clear the first interaction timestamp for later use. | 1103 // Clear the first interaction timestamp for later use. |
| 1092 first_interaction_time_ = base::Time(); | 1104 first_interaction_time_ = base::Time(); |
| 1093 } | 1105 } |
| 1094 | 1106 |
| 1095 void InstantController::ShowLoader(InstantShownReason reason, | 1107 void InstantController::ShowLoader(InstantShownReason reason, |
| 1096 int height, | 1108 int height, |
| 1097 InstantSizeUnits units) { | 1109 InstantSizeUnits units) { |
| 1098 // If we are on a committed search results page, the |loader_| is not in use. | 1110 // If we are on a committed search results page, the |loader_| is not in use. |
| 1099 if (instant_tab_) | 1111 if (instant_tab_) |
| 1100 return; | 1112 return; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1138 model_.SetPreviewState(search_mode_, height, units); | 1150 model_.SetPreviewState(search_mode_, height, units); |
| 1139 else | 1151 else |
| 1140 model_.SetPreviewState(search_mode_, 100, INSTANT_SIZE_PERCENT); | 1152 model_.SetPreviewState(search_mode_, 100, INSTANT_SIZE_PERCENT); |
| 1141 | 1153 |
| 1142 // If the user clicked on a query suggestion, also go ahead and commit the | 1154 // If the user clicked on a query suggestion, also go ahead and commit the |
| 1143 // overlay. This is necessary because if the overlay was partially visible | 1155 // overlay. This is necessary because if the overlay was partially visible |
| 1144 // when the suggestion was clicked, the click itself would not commit the | 1156 // when the suggestion was clicked, the click itself would not commit the |
| 1145 // overlay (because we're not full height). | 1157 // overlay (because we're not full height). |
| 1146 if (reason == INSTANT_SHOWN_CLICKED_QUERY_SUGGESTION) | 1158 if (reason == INSTANT_SHOWN_CLICKED_QUERY_SUGGESTION) |
| 1147 CommitIfPossible(INSTANT_COMMIT_CLICKED_QUERY_SUGGESTION); | 1159 CommitIfPossible(INSTANT_COMMIT_CLICKED_QUERY_SUGGESTION); |
| 1160 else if (extended_enabled_ && IsFullHeight(model_)) | |
| 1161 SetTransientHistoryEntry(); | |
| 1162 } | |
| 1163 | |
| 1164 void InstantController::SetTransientHistoryEntry() { | |
| 1165 content::WebContents* active_tab = browser_->GetActiveWebContents(); | |
| 1166 // Save any transient entry already associated with the active tab. | |
| 1167 content::NavigationEntry* old_transient_entry = | |
| 1168 active_tab->GetController().GetTransientEntry(); | |
| 1169 if (old_transient_entry && !instant_set_transient_entry_) | |
| 1170 saved_transient_entry_.reset( | |
| 1171 content::NavigationEntry::Create(*old_transient_entry)); | |
| 1172 // The loader's base navigation entry should describe the search provider | |
| 1173 // without reference to a specific query. The alternative, updating the query | |
| 1174 // in the tab title as the user types, would be distracting. | |
| 1175 const content::NavigationEntry* base_entry = loader_->base_navigation_entry(); | |
| 1176 DCHECK(base_entry != NULL); | |
| 1177 content::NavigationEntry* new_transient_entry = | |
| 1178 content::NavigationEntry::Create(*base_entry); | |
| 1179 active_tab->GetController().AddTransientEntry(new_transient_entry); | |
| 1180 instant_set_transient_entry_ = true; | |
| 1181 } | |
| 1182 | |
| 1183 void InstantController::UpdateTransientHistoryEntry(const GURL& url) { | |
| 1184 // URL should update so that if the user presses reload, we reload the page | |
| 1185 // for the current query, but title remains unchanged so it doesn't flicker. | |
| 1186 if (instant_set_transient_entry_) { | |
| 1187 content::WebContents* active_tab = browser_->GetActiveWebContents(); | |
| 1188 content::NavigationEntry* transient_entry = | |
| 1189 active_tab->GetController().GetTransientEntry(); | |
| 1190 transient_entry->SetURL(url); | |
| 1191 transient_entry->SetVirtualURL(url); | |
| 1192 } | |
| 1193 } | |
| 1194 | |
| 1195 void InstantController::ResetTransientHistoryEntry() { | |
| 1196 content::NavigationEntry* old_transient_entry = | |
| 1197 saved_transient_entry_.release(); | |
| 1198 if (old_transient_entry) { | |
| 1199 content::WebContents* active_tab = browser_->GetActiveWebContents(); | |
| 1200 active_tab->GetController().AddTransientEntry(old_transient_entry); | |
| 1201 chrome::search::SearchTabHelper::FromWebContents(active_tab)-> | |
| 1202 NavigationEntryUpdated(); | |
| 1203 } | |
| 1204 instant_set_transient_entry_ = false; | |
| 1148 } | 1205 } |
| 1149 | 1206 |
| 1150 void InstantController::SendPopupBoundsToPage() { | 1207 void InstantController::SendPopupBoundsToPage() { |
| 1151 if (last_popup_bounds_ == popup_bounds_ || !loader_ || | 1208 if (last_popup_bounds_ == popup_bounds_ || !loader_ || |
| 1152 loader_->is_pointer_down_from_activate()) | 1209 loader_->is_pointer_down_from_activate()) |
| 1153 return; | 1210 return; |
| 1154 | 1211 |
| 1155 last_popup_bounds_ = popup_bounds_; | 1212 last_popup_bounds_ = popup_bounds_; |
| 1156 gfx::Rect preview_bounds = browser_->GetInstantBounds(); | 1213 gfx::Rect preview_bounds = browser_->GetInstantBounds(); |
| 1157 gfx::Rect intersection = gfx::IntersectRects(popup_bounds_, preview_bounds); | 1214 gfx::Rect intersection = gfx::IntersectRects(popup_bounds_, preview_bounds); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1236 std::map<std::string, int>::const_iterator iter = | 1293 std::map<std::string, int>::const_iterator iter = |
| 1237 blacklisted_urls_.find(*instant_url); | 1294 blacklisted_urls_.find(*instant_url); |
| 1238 if (iter != blacklisted_urls_.end() && | 1295 if (iter != blacklisted_urls_.end() && |
| 1239 iter->second > kMaxInstantSupportFailures) { | 1296 iter->second > kMaxInstantSupportFailures) { |
| 1240 RecordEventHistogram(INSTANT_CONTROLLER_EVENT_URL_BLOCKED_BY_BLACKLIST); | 1297 RecordEventHistogram(INSTANT_CONTROLLER_EVENT_URL_BLOCKED_BY_BLACKLIST); |
| 1241 return false; | 1298 return false; |
| 1242 } | 1299 } |
| 1243 | 1300 |
| 1244 return true; | 1301 return true; |
| 1245 } | 1302 } |
| OLD | NEW |