Mark error pages as such on Ctrl-Shift-T reload.
When reloading a page whose url leads to an error page, a different
pathway is taken in NavigationControllerImpl. We must be careful to
check for unreachable urls in
NavigationControllerImpl::RendererDidNavigateToExistingPage() in this
case, and mark them as error pages.
BUG=458036
Review URL: https://codereview.chromium.org/917043004
Cr-Commit-Position: refs/heads/master@{#317046}
diff --git a/chrome/browser/ui/zoom/zoom_controller_browsertest.cc b/chrome/browser/ui/zoom/zoom_controller_browsertest.cc
index 378739d..a16336c1 100644
--- a/chrome/browser/ui/zoom/zoom_controller_browsertest.cc
+++ b/chrome/browser/ui/zoom/zoom_controller_browsertest.cc
@@ -8,6 +8,7 @@
#include "base/process/kill.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/webui/signin/login_ui_test_utils.h"
#include "chrome/browser/ui/zoom/chrome_zoom_level_prefs.h"
@@ -168,6 +169,57 @@
EXPECT_FLOAT_EQ(new_zoom_level, zoom_controller->GetZoomLevel());
}
+IN_PROC_BROWSER_TEST_F(ZoomControllerBrowserTest,
+ ErrorPagesCanZoomAfterTabRestore) {
+ // This url is meant to cause a network error page to be loaded.
+ // Tests can't reach the network, so this test should continue
+ // to work even if the domain listed is someday registered.
+ GURL url("http://kjfhkjsdf.com");
+
+ TabStripModel* tab_strip = browser()->tab_strip_model();
+ ASSERT_TRUE(tab_strip);
+
+ ui_test_utils::NavigateToURLWithDisposition(
+ browser(), url, NEW_FOREGROUND_TAB,
+ ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
+ {
+ content::WebContents* web_contents = tab_strip->GetActiveWebContents();
+
+ EXPECT_EQ(
+ content::PAGE_TYPE_ERROR,
+ web_contents->GetController().GetLastCommittedEntry()->GetPageType());
+
+ content::WebContentsDestroyedWatcher destroyed_watcher(web_contents);
+ tab_strip->CloseWebContentsAt(tab_strip->active_index(),
+ TabStripModel::CLOSE_CREATE_HISTORICAL_TAB);
+ destroyed_watcher.Wait();
+ }
+ EXPECT_EQ(1, tab_strip->count());
+
+ content::WebContentsAddedObserver new_web_contents_observer;
+ chrome::RestoreTab(browser());
+ content::WebContents* web_contents =
+ new_web_contents_observer.GetWebContents();
+ content::WaitForLoadStop(web_contents);
+
+ EXPECT_EQ(2, tab_strip->count());
+
+ EXPECT_EQ(
+ content::PAGE_TYPE_ERROR,
+ web_contents->GetController().GetLastCommittedEntry()->GetPageType());
+
+ ZoomController* zoom_controller =
+ ZoomController::FromWebContents(web_contents);
+
+ double old_zoom_level = zoom_controller->GetZoomLevel();
+ double new_zoom_level = old_zoom_level + 0.5;
+
+ // The following attempt to change the zoom level for an error page should
+ // fail.
+ zoom_controller->SetZoomLevel(new_zoom_level);
+ EXPECT_FLOAT_EQ(new_zoom_level, zoom_controller->GetZoomLevel());
+}
+
IN_PROC_BROWSER_TEST_F(ZoomControllerBrowserTest, Observe) {
content::WebContents* web_contents =
browser()->tab_strip_model()->GetActiveWebContents();
diff --git a/content/browser/frame_host/navigation_controller_impl.cc b/content/browser/frame_host/navigation_controller_impl.cc
index b358e55..faa0bbd 100644
--- a/content/browser/frame_host/navigation_controller_impl.cc
+++ b/content/browser/frame_host/navigation_controller_impl.cc
@@ -1057,10 +1057,6 @@
pending_entry_->site_instance() == rfh->GetSiteInstance())) {
new_entry = new NavigationEntryImpl(*pending_entry_);
- // Don't use the page type from the pending entry. Some interstitial page
- // may have set the type to interstitial. Once we commit, however, the page
- // type must always be normal.
- new_entry->set_page_type(PAGE_TYPE_NORMAL);
update_virtual_url = new_entry->update_virtual_url_with_url();
} else {
new_entry = new NavigationEntryImpl;
@@ -1081,8 +1077,11 @@
update_virtual_url = needs_update;
}
- if (params.url_is_unreachable)
- new_entry->set_page_type(PAGE_TYPE_ERROR);
+ // Don't use the page type from the pending entry. Some interstitial page
+ // may have set the type to interstitial. Once we commit, however, the page
+ // type must always be normal or error.
+ new_entry->set_page_type(params.url_is_unreachable ? PAGE_TYPE_ERROR
+ : PAGE_TYPE_NORMAL);
new_entry->SetURL(params.url);
if (update_virtual_url)
UpdateVirtualURLToURL(new_entry, params.url);
@@ -1133,6 +1132,8 @@
NavigationEntryImpl* entry = entries_[entry_index].get();
// The URL may have changed due to redirects.
+ entry->set_page_type(params.url_is_unreachable ? PAGE_TYPE_ERROR
+ : PAGE_TYPE_NORMAL);
entry->SetURL(params.url);
entry->SetReferrer(params.referrer);
if (entry->update_virtual_url_with_url())
@@ -1185,6 +1186,8 @@
existing_entry->set_unique_id(pending_entry_->GetUniqueID());
// The URL may have changed due to redirects.
+ existing_entry->set_page_type(params.url_is_unreachable ? PAGE_TYPE_ERROR
+ : PAGE_TYPE_NORMAL);
if (existing_entry->update_virtual_url_with_url())
UpdateVirtualURLToURL(existing_entry, params.url);
existing_entry->SetURL(params.url);
@@ -1211,6 +1214,8 @@
// entry and it will be the same page as the new navigation (minus the
// reference fragments, of course). We'll update the URL of the existing
// entry without pruning the forward history.
+ existing_entry->set_page_type(params.url_is_unreachable ? PAGE_TYPE_ERROR
+ : PAGE_TYPE_NORMAL);
existing_entry->SetURL(params.url);
if (existing_entry->update_virtual_url_with_url())
UpdateVirtualURLToURL(existing_entry, params.url);
diff --git a/content/browser/frame_host/navigation_controller_impl_unittest.cc b/content/browser/frame_host/navigation_controller_impl_unittest.cc
index 2a36a47..8642679 100644
--- a/content/browser/frame_host/navigation_controller_impl_unittest.cc
+++ b/content/browser/frame_host/navigation_controller_impl_unittest.cc
@@ -30,6 +30,7 @@
#include "content/public/browser/web_contents_observer.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/page_state.h"
+#include "content/public/common/page_type.h"
#include "content/public/common/url_constants.h"
#include "content/public/test/mock_render_process_host.h"
#include "content/public/test/test_notification_tracker.h"
@@ -4537,4 +4538,61 @@
EXPECT_EQ(0, delegate->repost_form_warning_count());
}
+TEST_F(NavigationControllerTest, UnreachableURLGivesErrorPage) {
+ GURL url("http://foo");
+ FrameHostMsg_DidCommitProvisionalLoad_Params params;
+ params.page_id = 1;
+ params.url = url;
+ params.transition = ui::PAGE_TRANSITION_LINK;
+ params.gesture = NavigationGestureUser;
+ params.page_state = PageState::CreateFromURL(url);
+ params.was_within_same_page = false;
+ params.is_post = true;
+ params.post_id = 2;
+ params.url_is_unreachable = true;
+ // Navigate to new page
+ {
+ LoadCommittedDetails details;
+ controller_impl().RendererDidNavigate(main_test_rfh(), params, &details);
+ EXPECT_EQ(PAGE_TYPE_ERROR,
+ controller_impl().GetLastCommittedEntry()->GetPageType());
+ EXPECT_EQ(NAVIGATION_TYPE_NEW_PAGE, details.type);
+ }
+
+ // Navigate to existing page.
+ {
+ LoadCommittedDetails details;
+ controller_impl().RendererDidNavigate(main_test_rfh(), params, &details);
+ EXPECT_EQ(PAGE_TYPE_ERROR,
+ controller_impl().GetLastCommittedEntry()->GetPageType());
+ EXPECT_EQ(NAVIGATION_TYPE_EXISTING_PAGE, details.type);
+ }
+
+ // Navigate to same page.
+ // Note: The call to LoadURL() creates a pending entry in order to trigger the
+ // same-page transition.
+ controller_impl().LoadURL(
+ url, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
+ params.transition = ui::PAGE_TRANSITION_TYPED;
+ {
+ LoadCommittedDetails details;
+ controller_impl().RendererDidNavigate(main_test_rfh(), params, &details);
+ EXPECT_EQ(PAGE_TYPE_ERROR,
+ controller_impl().GetLastCommittedEntry()->GetPageType());
+ EXPECT_EQ(NAVIGATION_TYPE_SAME_PAGE, details.type);
+ }
+
+ // Navigate in page.
+ params.url = GURL("http://foo#foo");
+ params.transition = ui::PAGE_TRANSITION_LINK;
+ params.was_within_same_page = true;
+ {
+ LoadCommittedDetails details;
+ controller_impl().RendererDidNavigate(main_test_rfh(), params, &details);
+ EXPECT_EQ(PAGE_TYPE_ERROR,
+ controller_impl().GetLastCommittedEntry()->GetPageType());
+ EXPECT_EQ(NAVIGATION_TYPE_IN_PAGE, details.type);
+ }
+}
+
} // namespace content