diff --git a/content/browser/frame_host/navigation_controller_impl.cc b/content/browser/frame_host/navigation_controller_impl.cc index ac57709fb7e36..32975719bc7d6 100644 --- a/content/browser/frame_host/navigation_controller_impl.cc +++ b/content/browser/frame_host/navigation_controller_impl.cc @@ -1864,6 +1864,21 @@ void NavigationControllerImpl::FindFramesToNavigate( new_item->document_sequence_number() == old_item->document_sequence_number()) { same_document_loads->push_back(std::make_pair(frame, new_item)); + + // TODO(avi, creis): This is a bug; we should not return here. Rather, we + // should continue on and navigate all child frames which have also + // changed. This bug is the cause of , which is + // a NC_IN_PAGE_NAVIGATION renderer kill. + // + // However, this bug is a bandaid over a deeper and worse problem. Doing a + // pushState immediately after loading a subframe is a race, one that no + // web page author expects. If we fix this bug, many large websites break. + // For example, see and the spec discussion at + // . + // + // For now, we accept this bug, and hope to resolve the race in a + // different way that will one day allow us to fix this. + return; } else { different_document_loads->push_back(std::make_pair(frame, new_item)); // For a different document, the subframes will be destroyed, so there's diff --git a/content/browser/frame_host/navigation_controller_impl_browsertest.cc b/content/browser/frame_host/navigation_controller_impl_browsertest.cc index 561f84ccc0f34..7d01f2a4173e0 100644 --- a/content/browser/frame_host/navigation_controller_impl_browsertest.cc +++ b/content/browser/frame_host/navigation_controller_impl_browsertest.cc @@ -3365,6 +3365,7 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, ReloadOriginalRequest) { // navigation history of a subframe when it is loaded, and 2) that that initial // "about:blank" returns if it is navigated to as part of a history navigation. // See http://crbug.com/542299 and https://github.com/whatwg/html/issues/546 . +// TODO(avi, creis): This test is partially neutered; fix it. IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, BackToAboutBlankIframe) { GURL original_url(embedded_test_server()->GetURL( @@ -3424,6 +3425,13 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, EXPECT_EQ(frame_url, frame->current_url()); + // At this point the rest of the test is inapplicable. The bug that it tests + // to be gone had to be reintroduced. + // + // See the discussion in NavigationControllerImpl::FindFramesToNavigate for + // more information. + +#if 0 // Go back. Because the old state had an empty frame, that should be restored // even though it was replaced in the second navigation entry. @@ -3437,12 +3445,14 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); EXPECT_EQ(GURL(url::kAboutBlankURL), frame->current_url()); +#endif } // This test is similar to "BackToAboutBlankIframe" above, except that a // fragment navigation is used rather than pushState (both create an in-page // navigation, so we need to test both), and an initial 'src' is given to the // iframe to test proper restoration in that case. +// TODO(avi, creis): This test is partially neutered; fix it. IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, BackToIframeWithContent) { GURL links_url(embedded_test_server()->GetURL( @@ -3507,6 +3517,13 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, EXPECT_EQ(frame_url_2, frame->current_url()); + // At this point the rest of the test is inapplicable. The bug that it tests + // to be gone had to be reintroduced. + // + // See the discussion in NavigationControllerImpl::FindFramesToNavigate for + // more information. + +#if 0 // Go back two entries. The original frame URL should be back. TestFrameNavigationObserver observer(frame); @@ -3519,6 +3536,7 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); EXPECT_EQ(frame_url_1, frame->current_url()); +#endif } // Ensure that we do not corrupt a NavigationEntry's PageState if a subframe diff --git a/content/renderer/history_controller.cc b/content/renderer/history_controller.cc index ae04b87791623..71c8ff0fb32f1 100644 --- a/content/renderer/history_controller.cc +++ b/content/renderer/history_controller.cc @@ -145,6 +145,11 @@ void HistoryController::RecursiveGoToEntry( new_item.documentSequenceNumber() == old_item.documentSequenceNumber()) { same_document_loads.push_back(std::make_pair(frame, new_item)); + + // Returning here (and omitting child frames which have also changed) is + // wrong, but not returning here is worse. See the discussion in + // NavigationControllerImpl::FindFramesToNavigate for more information. + return; } else { different_document_loads.push_back(std::make_pair(frame, new_item)); // For a different document, the subframes will be destroyed, so there's