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/search/instant_controller.h" | 5 #include "chrome/browser/ui/search/instant_controller.h" |
6 | 6 |
7 #include "base/metrics/histogram.h" | 7 #include "base/metrics/histogram.h" |
8 #include "base/string_util.h" | 8 #include "base/string_util.h" |
9 #include "base/stringprintf.h" | 9 #include "base/stringprintf.h" |
10 #include "base/utf_string_conversions.h" | 10 #include "base/utf_string_conversions.h" |
(...skipping 694 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
705 } | 705 } |
706 | 706 |
707 void InstantController::OmniboxNavigateToURL() { | 707 void InstantController::OmniboxNavigateToURL() { |
708 if (!extended_enabled_) | 708 if (!extended_enabled_) |
709 return; | 709 return; |
710 RecordNavigationHistogram(UsingLocalPage(), false); | 710 RecordNavigationHistogram(UsingLocalPage(), false); |
711 if (instant_tab_) | 711 if (instant_tab_) |
712 instant_tab_->Submit(string16()); | 712 instant_tab_->Submit(string16()); |
713 } | 713 } |
714 | 714 |
715 void InstantController::InstantPageLoadFailed(content::WebContents* contents) { | |
716 if (!chrome::ShouldPreferRemoteNTPOnStartup() || !extended_enabled_) { | |
717 // We only need to fall back on errors if we're showing the online page | |
718 // at startup, as otherwise we fall back correctly when trying to show | |
719 // a page that hasn't yet indicated that it supports the InstantExtended | |
720 // API. | |
721 return; | |
722 } | |
723 | |
724 if (IsContentsFrom(instant_tab(), contents)) { | |
725 // Verify we're not already on a local page and that the URL precisely | |
726 // equals the instant_url (minus the query params, as those will be filled | |
727 // in by template values). This check is necessary to make sure we don't | |
728 // inadvertently redirect to the local NTP if someone, say, reloads a SRP | |
729 // while offline, as a committed results page still counts as an instant | |
730 // url. | |
731 const GURL current_url = contents->GetURL(); | |
sreeram
2013/05/05 08:40:39
const GURL&
David Black
2013/05/05 20:02:42
Done.
| |
732 if (instant_tab_->IsLocal() || | |
733 !chrome::MatchesOriginAndPath(GURL(GetInstantURL()), current_url) || | |
734 !current_url.ref().empty()) | |
735 return; | |
736 LOG_INSTANT_DEBUG_EVENT(this, "InstantPageLoadFailed: instant_tab"); | |
Jered
2013/05/05 15:08:00
So when do we get in here exactly? I think just on
sreeram
2013/05/05 16:38:13
Yes, instant_url has /webhp. But, it's possible th
Jered
2013/05/05 16:59:13
Wow, ok, thanks for the explanation. Wheels within
| |
737 RedirectToLocalNTP(contents); | |
738 } else if (IsContentsFrom(ntp(), contents)) { | |
739 LOG_INSTANT_DEBUG_EVENT(this, "InstantPageLoadFailed: ntp"); | |
740 bool is_local = ntp_->IsLocal(); | |
741 DeletePageSoon(ntp_.Pass()); | |
742 if (!is_local) | |
743 ResetNTP(GetLocalInstantURL()); | |
744 } else if (IsContentsFrom(overlay(), contents)) { | |
745 LOG_INSTANT_DEBUG_EVENT(this, "InstantPageLoadFailed: overlay"); | |
746 bool is_local = overlay_->IsLocal(); | |
747 DeletePageSoon(overlay_.Pass()); | |
748 if (!is_local) | |
749 ResetOverlay(GetLocalInstantURL()); | |
750 } | |
751 } | |
752 | |
715 content::WebContents* InstantController::GetOverlayContents() const { | 753 content::WebContents* InstantController::GetOverlayContents() const { |
716 return overlay_ ? overlay_->contents() : NULL; | 754 return overlay_ ? overlay_->contents() : NULL; |
717 } | 755 } |
718 | 756 |
719 bool InstantController::IsOverlayingSearchResults() const { | 757 bool InstantController::IsOverlayingSearchResults() const { |
720 return model_.mode().is_search_suggestions() && IsFullHeight(model_) && | 758 return model_.mode().is_search_suggestions() && IsFullHeight(model_) && |
721 (last_match_was_search_ || | 759 (last_match_was_search_ || |
722 last_suggestion_.behavior == INSTANT_COMPLETE_NEVER); | 760 last_suggestion_.behavior == INSTANT_COMPLETE_NEVER); |
723 } | 761 } |
724 | 762 |
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1129 bool supports_instant) { | 1167 bool supports_instant) { |
1130 if (IsContentsFrom(instant_tab(), contents)) { | 1168 if (IsContentsFrom(instant_tab(), contents)) { |
1131 if (!supports_instant) | 1169 if (!supports_instant) |
1132 MessageLoop::current()->DeleteSoon(FROM_HERE, instant_tab_.release()); | 1170 MessageLoop::current()->DeleteSoon(FROM_HERE, instant_tab_.release()); |
1133 | 1171 |
1134 content::NotificationService::current()->Notify( | 1172 content::NotificationService::current()->Notify( |
1135 chrome::NOTIFICATION_INSTANT_TAB_SUPPORT_DETERMINED, | 1173 chrome::NOTIFICATION_INSTANT_TAB_SUPPORT_DETERMINED, |
1136 content::Source<InstantController>(this), | 1174 content::Source<InstantController>(this), |
1137 content::NotificationService::NoDetails()); | 1175 content::NotificationService::NoDetails()); |
1138 } else if (IsContentsFrom(ntp(), contents)) { | 1176 } else if (IsContentsFrom(ntp(), contents)) { |
1139 if (!supports_instant) | 1177 if (!supports_instant) { |
1178 bool is_local = ntp_->IsLocal(); | |
1140 DeletePageSoon(ntp_.Pass()); | 1179 DeletePageSoon(ntp_.Pass()); |
1180 // Preload a local NTP in place of the broken online one. | |
1181 if (!is_local) | |
1182 ResetNTP(GetLocalInstantURL()); | |
1183 } | |
1141 | 1184 |
1142 content::NotificationService::current()->Notify( | 1185 content::NotificationService::current()->Notify( |
1143 chrome::NOTIFICATION_INSTANT_NTP_SUPPORT_DETERMINED, | 1186 chrome::NOTIFICATION_INSTANT_NTP_SUPPORT_DETERMINED, |
1144 content::Source<InstantController>(this), | 1187 content::Source<InstantController>(this), |
1145 content::NotificationService::NoDetails()); | 1188 content::NotificationService::NoDetails()); |
1146 | 1189 |
1147 } else if (IsContentsFrom(overlay(), contents)) { | 1190 } else if (IsContentsFrom(overlay(), contents)) { |
1148 if (!supports_instant) { | 1191 if (!supports_instant) { |
1149 HideInternal(); | 1192 HideInternal(); |
1193 bool is_local = overlay_->IsLocal(); | |
1150 DeletePageSoon(overlay_.Pass()); | 1194 DeletePageSoon(overlay_.Pass()); |
1195 // Preload a local overlay in place of the broken online one. | |
1196 if (!is_local && extended_enabled_) | |
1197 ResetOverlay(GetLocalInstantURL()); | |
1151 } | 1198 } |
1152 | 1199 |
1153 content::NotificationService::current()->Notify( | 1200 content::NotificationService::current()->Notify( |
1154 chrome::NOTIFICATION_INSTANT_OVERLAY_SUPPORT_DETERMINED, | 1201 chrome::NOTIFICATION_INSTANT_OVERLAY_SUPPORT_DETERMINED, |
1155 content::Source<InstantController>(this), | 1202 content::Source<InstantController>(this), |
1156 content::NotificationService::NoDetails()); | 1203 content::NotificationService::NoDetails()); |
1157 } | 1204 } |
1158 } | 1205 } |
1159 | 1206 |
1160 void InstantController::InstantPageRenderViewGone( | 1207 void InstantController::InstantPageRenderViewGone( |
1161 const content::WebContents* contents) { | 1208 const content::WebContents* contents) { |
1162 if (IsContentsFrom(overlay(), contents)) { | 1209 if (IsContentsFrom(overlay(), contents)) { |
1163 HideInternal(); | 1210 HideInternal(); |
1164 DeletePageSoon(overlay_.Pass()); | 1211 DeletePageSoon(overlay_.Pass()); |
1165 } else if (IsContentsFrom(ntp(), contents)) { | 1212 } else if (IsContentsFrom(ntp(), contents)) { |
1166 DeletePageSoon(ntp_.Pass()); | 1213 DeletePageSoon(ntp_.Pass()); |
1167 } else { | 1214 } else { |
1168 NOTREACHED(); | 1215 NOTREACHED(); |
1169 } | 1216 } |
1170 } | 1217 } |
1171 | 1218 |
1172 void InstantController::InstantPageAboutToNavigateMainFrame( | 1219 void InstantController::InstantPageAboutToNavigateMainFrame( |
1173 const content::WebContents* contents, | 1220 const content::WebContents* contents, |
1174 const GURL& url) { | 1221 const GURL& url) { |
1175 DCHECK(IsContentsFrom(overlay(), contents)); | 1222 if (IsContentsFrom(overlay(), contents)) { |
1223 // If the page does not yet support Instant, we allow redirects and other | |
1224 // navigations to go through since the Instant URL can redirect - e.g. to | |
1225 // country specific pages. | |
1226 if (!overlay_->supports_instant()) | |
1227 return; | |
1176 | 1228 |
1177 // If the page does not yet support Instant, we allow redirects and other | 1229 GURL instant_url(overlay_->instant_url()); |
1178 // navigations to go through since the Instant URL can redirect - e.g. to | |
1179 // country specific pages. | |
1180 if (!overlay_->supports_instant()) | |
1181 return; | |
1182 | 1230 |
1183 GURL instant_url(overlay_->instant_url()); | 1231 // If we are navigating to the Instant URL, do nothing. |
1232 if (url == instant_url) | |
1233 return; | |
1184 | 1234 |
1185 // If we are navigating to the Instant URL, do nothing. | 1235 // Commit the navigation if either: |
1186 if (url == instant_url) | 1236 // - The page is in NTP mode (so it could only navigate on a user click) or |
1187 return; | 1237 // - The page is not in NTP mode and we are navigating to a URL with a |
1188 | 1238 // different host or path than the Instant URL. This enables the instant |
1189 // Commit the navigation if either: | 1239 // page when it is showing search results to change the query parameters |
1190 // - The page is in NTP mode (so it could only navigate on a user click) or | 1240 // and fragments of the URL without it navigating. |
1191 // - The page is not in NTP mode and we are navigating to a URL with a | 1241 if (model_.mode().is_ntp() || |
1192 // different host or path than the Instant URL. This enables the instant | 1242 (url.host() != instant_url.host() || |
1193 // page when it is showing search results to change the query parameters | 1243 url.path() != instant_url.path())) { |
1194 // and fragments of the URL without it navigating. | 1244 CommitIfPossible(INSTANT_COMMIT_NAVIGATED); |
1195 if (model_.mode().is_ntp() || | 1245 } |
1196 (url.host() != instant_url.host() || url.path() != instant_url.path())) { | 1246 } else if (IsContentsFrom(instant_tab(), contents)) { |
1197 CommitIfPossible(INSTANT_COMMIT_NAVIGATED); | 1247 // The Instant tab navigated. Send it the data it needs to display |
1248 // properly. | |
1249 UpdateInfoForInstantTab(); | |
1250 } else { | |
1251 NOTREACHED(); | |
1198 } | 1252 } |
1199 } | 1253 } |
1200 | 1254 |
1201 void InstantController::SetSuggestions( | 1255 void InstantController::SetSuggestions( |
1202 const content::WebContents* contents, | 1256 const content::WebContents* contents, |
1203 const std::vector<InstantSuggestion>& suggestions) { | 1257 const std::vector<InstantSuggestion>& suggestions) { |
1204 LOG_INSTANT_DEBUG_EVENT(this, "SetSuggestions"); | 1258 LOG_INSTANT_DEBUG_EVENT(this, "SetSuggestions"); |
1205 | 1259 |
1206 // Ignore if the message is from an unexpected source. | 1260 // Ignore if the message is from an unexpected source. |
1207 if (IsContentsFrom(ntp(), contents)) | 1261 if (IsContentsFrom(ntp(), contents)) |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1445 | 1499 |
1446 void InstantController::ResetInstantTab() { | 1500 void InstantController::ResetInstantTab() { |
1447 // Do not wire up the InstantTab in Incognito, to prevent it from sending data | 1501 // Do not wire up the InstantTab in Incognito, to prevent it from sending data |
1448 // to the page. | 1502 // to the page. |
1449 if (!search_mode_.is_origin_default() && | 1503 if (!search_mode_.is_origin_default() && |
1450 !browser_->profile()->IsOffTheRecord()) { | 1504 !browser_->profile()->IsOffTheRecord()) { |
1451 content::WebContents* active_tab = browser_->GetActiveWebContents(); | 1505 content::WebContents* active_tab = browser_->GetActiveWebContents(); |
1452 if (!instant_tab_ || active_tab != instant_tab_->contents()) { | 1506 if (!instant_tab_ || active_tab != instant_tab_->contents()) { |
1453 instant_tab_.reset(new InstantTab(this)); | 1507 instant_tab_.reset(new InstantTab(this)); |
1454 instant_tab_->Init(active_tab); | 1508 instant_tab_->Init(active_tab); |
1455 // Update theme info for this tab. | 1509 UpdateInfoForInstantTab(); |
1456 browser_->UpdateThemeInfo(); | |
1457 instant_tab_->SetDisplayInstantResults(instant_enabled_); | |
1458 instant_tab_->SetOmniboxBounds(omnibox_bounds_); | |
1459 instant_tab_->InitializeFonts(); | |
1460 StartListeningToMostVisitedChanges(); | |
1461 instant_tab_->KeyCaptureChanged( | |
1462 omnibox_focus_state_ == OMNIBOX_FOCUS_INVISIBLE); | |
1463 } | 1510 } |
1464 | 1511 |
1465 // Hide the |overlay_| since we are now using |instant_tab_| instead. | 1512 // Hide the |overlay_| since we are now using |instant_tab_| instead. |
1466 HideOverlay(); | 1513 HideOverlay(); |
1467 } else { | 1514 } else { |
1468 instant_tab_.reset(); | 1515 instant_tab_.reset(); |
1469 } | 1516 } |
1470 } | 1517 } |
1471 | 1518 |
1519 void InstantController::UpdateInfoForInstantTab() { | |
1520 if (instant_tab_) { | |
1521 browser_->UpdateThemeInfo(); | |
1522 instant_tab_->SetDisplayInstantResults(instant_enabled_); | |
1523 instant_tab_->SetOmniboxBounds(omnibox_bounds_); | |
1524 instant_tab_->InitializeFonts(); | |
1525 StartListeningToMostVisitedChanges(); | |
1526 instant_tab_->KeyCaptureChanged( | |
1527 omnibox_focus_state_ == OMNIBOX_FOCUS_INVISIBLE); | |
1528 } | |
1529 } | |
1530 | |
1472 void InstantController::HideOverlay() { | 1531 void InstantController::HideOverlay() { |
1473 HideInternal(); | 1532 HideInternal(); |
1474 ReloadOverlayIfStale(); | 1533 ReloadOverlayIfStale(); |
1475 } | 1534 } |
1476 | 1535 |
1477 void InstantController::HideInternal() { | 1536 void InstantController::HideInternal() { |
1478 LOG_INSTANT_DEBUG_EVENT(this, "Hide"); | 1537 LOG_INSTANT_DEBUG_EVENT(this, "Hide"); |
1479 | 1538 |
1480 // If GetOverlayContents() returns NULL, either we're already in the desired | 1539 // If GetOverlayContents() returns NULL, either we're already in the desired |
1481 // MODE_DEFAULT state, or we're in the commit path. For the latter, don't | 1540 // MODE_DEFAULT state, or we're in the commit path. For the latter, don't |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1685 } | 1744 } |
1686 } | 1745 } |
1687 | 1746 |
1688 return false; | 1747 return false; |
1689 } | 1748 } |
1690 | 1749 |
1691 bool InstantController::UsingLocalPage() const { | 1750 bool InstantController::UsingLocalPage() const { |
1692 return (instant_tab_ && instant_tab_->IsLocal()) || | 1751 return (instant_tab_ && instant_tab_->IsLocal()) || |
1693 (!instant_tab_ && overlay_ && overlay_->IsLocal()); | 1752 (!instant_tab_ && overlay_ && overlay_->IsLocal()); |
1694 } | 1753 } |
1754 | |
1755 void InstantController::RedirectToLocalNTP(content::WebContents* contents) { | |
1756 contents->GetController().LoadURL( | |
1757 chrome::GetLocalInstantURL(browser_->profile()), | |
1758 content::Referrer(), | |
1759 content::PAGE_TRANSITION_SERVER_REDIRECT, | |
1760 std::string()); // No extra headers. | |
1761 // TODO(dcblack): Remove extraneous history entry caused by 404s. | |
1762 // Note that the base case of a 204 being returned doesn't push a history | |
1763 // entry. | |
sreeram
2013/05/05 08:40:39
Won't this nuke the "Forward" history in the Back/
David Black
2013/05/05 20:02:42
Yes, good point. Added a check to not redirect in
| |
1764 } | |
OLD | NEW |