OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "content/browser/frame_host/navigation_controller_impl.h" | 5 #include "content/browser/frame_host/navigation_controller_impl.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 711 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
722 EXPECT_EQ(2, controller.GetEntryCount()); | 722 EXPECT_EQ(2, controller.GetEntryCount()); |
723 } | 723 } |
724 | 724 |
725 // Make a new entry ... | 725 // Make a new entry ... |
726 NavigateToURL(shell(), GURL(url::kAboutBlankURL)); | 726 NavigateToURL(shell(), GURL(url::kAboutBlankURL)); |
727 EXPECT_EQ(3, controller.GetEntryCount()); | 727 EXPECT_EQ(3, controller.GetEntryCount()); |
728 | 728 |
729 // ... and replace it with a failed load. | 729 // ... and replace it with a failed load. |
730 // TODO(creis): Make this be NEW_PAGE along with the other location.replace | 730 // TODO(creis): Make this be NEW_PAGE along with the other location.replace |
731 // cases. There isn't much impact to having this be EXISTING_PAGE for now. | 731 // cases. There isn't much impact to having this be EXISTING_PAGE for now. |
732 // See https://crbug.com/317872. | 732 // See https://crbug.com/596707. |
733 { | 733 { |
734 FrameNavigateParamsCapturer capturer(root); | 734 FrameNavigateParamsCapturer capturer(root); |
735 NavigateToURLAndReplace(shell(), error_url); | 735 NavigateToURLAndReplace(shell(), error_url); |
736 capturer.Wait(); | 736 capturer.Wait(); |
737 EXPECT_EQ(NAVIGATION_TYPE_EXISTING_PAGE, capturer.details().type); | 737 EXPECT_EQ(NAVIGATION_TYPE_EXISTING_PAGE, capturer.details().type); |
738 NavigationEntry* entry = controller.GetLastCommittedEntry(); | 738 NavigationEntry* entry = controller.GetLastCommittedEntry(); |
739 EXPECT_EQ(PAGE_TYPE_ERROR, entry->GetPageType()); | 739 EXPECT_EQ(PAGE_TYPE_ERROR, entry->GetPageType()); |
740 EXPECT_EQ(3, controller.GetEntryCount()); | 740 EXPECT_EQ(3, controller.GetEntryCount()); |
741 } | 741 } |
742 | 742 |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
960 capturer.Wait(); | 960 capturer.Wait(); |
961 EXPECT_EQ(ui::PAGE_TRANSITION_LINK | ui::PAGE_TRANSITION_CLIENT_REDIRECT, | 961 EXPECT_EQ(ui::PAGE_TRANSITION_LINK | ui::PAGE_TRANSITION_CLIENT_REDIRECT, |
962 capturer.params().transition); | 962 capturer.params().transition); |
963 EXPECT_EQ(NAVIGATION_TYPE_EXISTING_PAGE, capturer.details().type); | 963 EXPECT_EQ(NAVIGATION_TYPE_EXISTING_PAGE, capturer.details().type); |
964 EXPECT_FALSE(capturer.details().is_in_page); | 964 EXPECT_FALSE(capturer.details().is_in_page); |
965 } | 965 } |
966 | 966 |
967 { | 967 { |
968 // location.replace(). | 968 // location.replace(). |
969 // TODO(creis): Change this to be NEW_PAGE with replacement in | 969 // TODO(creis): Change this to be NEW_PAGE with replacement in |
970 // https://crbug.com/317872. | 970 // https://crbug.com/596707. |
971 FrameNavigateParamsCapturer capturer(root); | 971 FrameNavigateParamsCapturer capturer(root); |
972 GURL frame_url(embedded_test_server()->GetURL( | 972 GURL frame_url(embedded_test_server()->GetURL( |
973 "/navigation_controller/simple_page_1.html")); | 973 "/navigation_controller/simple_page_1.html")); |
974 std::string script = "location.replace('" + frame_url.spec() + "')"; | 974 std::string script = "location.replace('" + frame_url.spec() + "')"; |
975 EXPECT_TRUE(ExecuteScript(root->current_frame_host(), script)); | 975 EXPECT_TRUE(ExecuteScript(root->current_frame_host(), script)); |
976 capturer.Wait(); | 976 capturer.Wait(); |
977 EXPECT_EQ(ui::PAGE_TRANSITION_LINK | ui::PAGE_TRANSITION_CLIENT_REDIRECT, | 977 EXPECT_EQ(ui::PAGE_TRANSITION_LINK | ui::PAGE_TRANSITION_CLIENT_REDIRECT, |
978 capturer.params().transition); | 978 capturer.params().transition); |
979 EXPECT_EQ(NAVIGATION_TYPE_EXISTING_PAGE, capturer.details().type); | 979 EXPECT_EQ(NAVIGATION_TYPE_EXISTING_PAGE, capturer.details().type); |
980 EXPECT_FALSE(capturer.details().is_in_page); | 980 EXPECT_FALSE(capturer.details().is_in_page); |
(...skipping 1279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2260 EXPECT_EQ(frame_url_b, | 2260 EXPECT_EQ(frame_url_b, |
2261 entry4->root_node()->children[0]->frame_entry->url()); | 2261 entry4->root_node()->children[0]->frame_entry->url()); |
2262 EXPECT_EQ( | 2262 EXPECT_EQ( |
2263 frame_url_c, | 2263 frame_url_c, |
2264 entry4->root_node()->children[0]->children[0]->frame_entry->url()); | 2264 entry4->root_node()->children[0]->children[0]->frame_entry->url()); |
2265 } else { | 2265 } else { |
2266 // There are no subframe FrameNavigationEntries by default. | 2266 // There are no subframe FrameNavigationEntries by default. |
2267 EXPECT_EQ(0U, entry4->root_node()->children.size()); | 2267 EXPECT_EQ(0U, entry4->root_node()->children.size()); |
2268 } | 2268 } |
2269 | 2269 |
| 2270 // Inject a JS value so that we can check for it later. |
| 2271 EXPECT_TRUE(content::ExecuteScript(root->current_frame_host(), "foo=3;")); |
| 2272 |
2270 // 7. Go back again, to the data URL in the nested iframe. | 2273 // 7. Go back again, to the data URL in the nested iframe. |
2271 { | 2274 { |
2272 TestNavigationObserver back_load_observer(shell()->web_contents()); | 2275 TestNavigationObserver back_load_observer(shell()->web_contents()); |
2273 shell()->web_contents()->GetController().GoBack(); | 2276 shell()->web_contents()->GetController().GoBack(); |
2274 back_load_observer.Wait(); | 2277 back_load_observer.Wait(); |
2275 } | 2278 } |
2276 ASSERT_EQ(1U, root->child_count()); | 2279 ASSERT_EQ(1U, root->child_count()); |
2277 ASSERT_EQ(1U, root->child_at(0)->child_count()); | 2280 ASSERT_EQ(1U, root->child_at(0)->child_count()); |
2278 EXPECT_EQ(main_url_a, root->current_url()); | 2281 EXPECT_EQ(main_url_a, root->current_url()); |
2279 EXPECT_EQ(frame_url_b, root->child_at(0)->current_url()); | 2282 EXPECT_EQ(frame_url_b, root->child_at(0)->current_url()); |
(...skipping 11 matching lines...) Expand all Loading... |
2291 EXPECT_EQ(frame_url_b, | 2294 EXPECT_EQ(frame_url_b, |
2292 entry3->root_node()->children[0]->frame_entry->url()); | 2295 entry3->root_node()->children[0]->frame_entry->url()); |
2293 EXPECT_EQ( | 2296 EXPECT_EQ( |
2294 data_url, | 2297 data_url, |
2295 entry3->root_node()->children[0]->children[0]->frame_entry->url()); | 2298 entry3->root_node()->children[0]->children[0]->frame_entry->url()); |
2296 } else { | 2299 } else { |
2297 // There are no subframe FrameNavigationEntries by default. | 2300 // There are no subframe FrameNavigationEntries by default. |
2298 EXPECT_EQ(0U, entry3->root_node()->children.size()); | 2301 EXPECT_EQ(0U, entry3->root_node()->children.size()); |
2299 } | 2302 } |
2300 | 2303 |
| 2304 // Verify that we did not reload the main frame. See https://crbug.com/586234. |
| 2305 { |
| 2306 int value = 0; |
| 2307 EXPECT_TRUE(ExecuteScriptAndExtractInt(root->current_frame_host(), |
| 2308 "domAutomationController.send(foo)", |
| 2309 &value)); |
| 2310 EXPECT_EQ(3, value); |
| 2311 } |
| 2312 |
2301 // 8. Go back again, to the data URL in the first subframe. | 2313 // 8. Go back again, to the data URL in the first subframe. |
2302 { | 2314 { |
2303 TestNavigationObserver back_load_observer(shell()->web_contents()); | 2315 TestNavigationObserver back_load_observer(shell()->web_contents()); |
2304 shell()->web_contents()->GetController().GoBack(); | 2316 shell()->web_contents()->GetController().GoBack(); |
2305 back_load_observer.Wait(); | 2317 back_load_observer.Wait(); |
2306 } | 2318 } |
2307 ASSERT_EQ(1U, root->child_count()); | 2319 ASSERT_EQ(1U, root->child_count()); |
2308 ASSERT_EQ(0U, root->child_at(0)->child_count()); | 2320 ASSERT_EQ(0U, root->child_at(0)->child_count()); |
2309 EXPECT_EQ(main_url_a, root->current_url()); | 2321 EXPECT_EQ(main_url_a, root->current_url()); |
2310 EXPECT_EQ(data_url, root->child_at(0)->current_url()); | 2322 EXPECT_EQ(data_url, root->child_at(0)->current_url()); |
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2686 } else { | 2698 } else { |
2687 EXPECT_NE(main_site_instance, | 2699 EXPECT_NE(main_site_instance, |
2688 foo_subframe->current_frame_host()->GetSiteInstance()); | 2700 foo_subframe->current_frame_host()->GetSiteInstance()); |
2689 } | 2701 } |
2690 | 2702 |
2691 foo_subframe_entry = | 2703 foo_subframe_entry = |
2692 controller.GetLastCommittedEntry()->GetFrameEntry(foo_subframe); | 2704 controller.GetLastCommittedEntry()->GetFrameEntry(foo_subframe); |
2693 EXPECT_EQ(named_subframe_name, foo_subframe_entry->frame_unique_name()); | 2705 EXPECT_EQ(named_subframe_name, foo_subframe_entry->frame_unique_name()); |
2694 } | 2706 } |
2695 | 2707 |
| 2708 // Ensure we don't crash when cloning a named window. This happened in |
| 2709 // https://crbug.com/603245 because neither the FrameTreeNode ID nor the name of |
| 2710 // the cloned window matched the root FrameNavigationEntry. |
| 2711 IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, CloneNamedWindow) { |
| 2712 // Start on an initial page. |
| 2713 GURL url_1(embedded_test_server()->GetURL( |
| 2714 "/navigation_controller/simple_page_1.html")); |
| 2715 EXPECT_TRUE(NavigateToURL(shell(), url_1)); |
| 2716 |
| 2717 // Name the window. |
| 2718 EXPECT_TRUE(ExecuteScript(shell()->web_contents(), "window.name = 'foo';")); |
| 2719 |
| 2720 // Navigate it. |
| 2721 GURL url_2(embedded_test_server()->GetURL( |
| 2722 "/navigation_controller/simple_page_2.html")); |
| 2723 EXPECT_TRUE(NavigateToURL(shell(), url_2)); |
| 2724 |
| 2725 // Clone the tab and load the page. |
| 2726 std::unique_ptr<WebContentsImpl> new_tab( |
| 2727 static_cast<WebContentsImpl*>(shell()->web_contents()->Clone())); |
| 2728 NavigationController& new_controller = new_tab->GetController(); |
| 2729 EXPECT_TRUE(new_controller.IsInitialNavigation()); |
| 2730 EXPECT_TRUE(new_controller.NeedsReload()); |
| 2731 { |
| 2732 TestNavigationObserver clone_observer(new_tab.get()); |
| 2733 new_controller.LoadIfNecessary(); |
| 2734 clone_observer.Wait(); |
| 2735 } |
| 2736 } |
| 2737 |
| 2738 // Ensure we don't crash when going back in a cloned named window. This |
| 2739 // happened in https://crbug.com/603245 because neither the FrameTreeNode ID nor |
| 2740 // the name of the cloned window matched the root FrameNavigationEntry. |
| 2741 IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, |
| 2742 CloneAndGoBackWithNamedWindow) { |
| 2743 // Start on an initial page. |
| 2744 GURL url_1(embedded_test_server()->GetURL( |
| 2745 "/navigation_controller/simple_page_1.html")); |
| 2746 EXPECT_TRUE(NavigateToURL(shell(), url_1)); |
| 2747 |
| 2748 // Name the window. |
| 2749 EXPECT_TRUE(ExecuteScript(shell()->web_contents(), "window.name = 'foo';")); |
| 2750 |
| 2751 // Navigate it. |
| 2752 GURL url_2(embedded_test_server()->GetURL( |
| 2753 "/navigation_controller/simple_page_2.html")); |
| 2754 EXPECT_TRUE(NavigateToURL(shell(), url_2)); |
| 2755 |
| 2756 // Clear the name. |
| 2757 EXPECT_TRUE(ExecuteScript(shell()->web_contents(), "window.name = '';")); |
| 2758 |
| 2759 // Navigate it again. |
| 2760 EXPECT_TRUE(NavigateToURL(shell(), url_1)); |
| 2761 |
| 2762 // Clone the tab and load the page. |
| 2763 std::unique_ptr<WebContentsImpl> new_tab( |
| 2764 static_cast<WebContentsImpl*>(shell()->web_contents()->Clone())); |
| 2765 NavigationController& new_controller = new_tab->GetController(); |
| 2766 EXPECT_TRUE(new_controller.IsInitialNavigation()); |
| 2767 EXPECT_TRUE(new_controller.NeedsReload()); |
| 2768 { |
| 2769 TestNavigationObserver clone_observer(new_tab.get()); |
| 2770 new_controller.LoadIfNecessary(); |
| 2771 clone_observer.Wait(); |
| 2772 } |
| 2773 |
| 2774 // Go back. |
| 2775 { |
| 2776 TestNavigationObserver back_load_observer(new_tab.get()); |
| 2777 new_controller.GoBack(); |
| 2778 back_load_observer.Wait(); |
| 2779 } |
| 2780 } |
| 2781 |
| 2782 // Ensures that FrameNavigationEntries for dynamically added iframes can be |
| 2783 // found correctly when cloning them during a transfer. If we don't look for |
| 2784 // them based on unique name in AddOrUpdateFrameEntry, the FrameTreeNode ID |
| 2785 // mismatch will cause us to create a second FrameNavigationEntry during the |
| 2786 // transfer. Later, we'll find the wrong FrameNavigationEntry (the earlier one |
| 2787 // from the clone which still has a PageState), and this will cause the renderer |
| 2788 // to crash in NavigateInternal because the PageState is present but the page_id |
| 2789 // is -1 (similar to https://crbug.com/568703). See https://crbug.com/568768. |
| 2790 IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, |
| 2791 FrameNavigationEntry_RepeatCreatedFrame) { |
| 2792 NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( |
| 2793 shell()->web_contents()->GetController()); |
| 2794 |
| 2795 // 1. Navigate the main frame. |
| 2796 GURL url(embedded_test_server()->GetURL( |
| 2797 "/navigation_controller/page_with_links.html")); |
| 2798 EXPECT_TRUE(NavigateToURL(shell(), url)); |
| 2799 FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) |
| 2800 ->GetFrameTree() |
| 2801 ->root(); |
| 2802 SiteInstance* main_site_instance = |
| 2803 root->current_frame_host()->GetSiteInstance(); |
| 2804 |
| 2805 // 2. Add a cross-site subframe. |
| 2806 GURL frame_url(embedded_test_server()->GetURL( |
| 2807 "foo.com", "/navigation_controller/simple_page_1.html")); |
| 2808 std::string script = "var iframe = document.createElement('iframe');" |
| 2809 "iframe.src = '" + frame_url.spec() + "';" |
| 2810 "document.body.appendChild(iframe);"; |
| 2811 { |
| 2812 LoadCommittedCapturer capturer(shell()->web_contents()); |
| 2813 EXPECT_TRUE(ExecuteScript(root->current_frame_host(), script)); |
| 2814 capturer.Wait(); |
| 2815 EXPECT_EQ(ui::PAGE_TRANSITION_AUTO_SUBFRAME, capturer.transition_type()); |
| 2816 } |
| 2817 |
| 2818 FrameTreeNode* subframe = root->child_at(0); |
| 2819 if (AreAllSitesIsolatedForTesting()) { |
| 2820 EXPECT_NE(main_site_instance, |
| 2821 subframe->current_frame_host()->GetSiteInstance()); |
| 2822 } |
| 2823 if (SiteIsolationPolicy::UseSubframeNavigationEntries()) { |
| 2824 FrameNavigationEntry* subframe_entry = |
| 2825 controller.GetLastCommittedEntry()->GetFrameEntry(subframe); |
| 2826 EXPECT_EQ(frame_url, subframe_entry->url()); |
| 2827 } |
| 2828 |
| 2829 // 3. Reload the main frame. |
| 2830 { |
| 2831 FrameNavigateParamsCapturer capturer(root); |
| 2832 controller.Reload(false); |
| 2833 capturer.Wait(); |
| 2834 EXPECT_EQ(ui::PAGE_TRANSITION_RELOAD, capturer.params().transition); |
| 2835 EXPECT_EQ(NAVIGATION_TYPE_EXISTING_PAGE, capturer.details().type); |
| 2836 EXPECT_FALSE(capturer.details().is_in_page); |
| 2837 } |
| 2838 |
| 2839 // 4. Add the iframe again. |
| 2840 { |
| 2841 LoadCommittedCapturer capturer(shell()->web_contents()); |
| 2842 EXPECT_TRUE(ExecuteScript(root->current_frame_host(), script)); |
| 2843 capturer.Wait(); |
| 2844 EXPECT_EQ(ui::PAGE_TRANSITION_AUTO_SUBFRAME, capturer.transition_type()); |
| 2845 } |
| 2846 if (AreAllSitesIsolatedForTesting()) { |
| 2847 EXPECT_NE(main_site_instance, |
| 2848 root->child_at(0)->current_frame_host()->GetSiteInstance()); |
| 2849 } |
| 2850 } |
| 2851 |
2696 // Verifies that item sequence numbers and document sequence numbers update | 2852 // Verifies that item sequence numbers and document sequence numbers update |
2697 // properly for main frames and subframes. | 2853 // properly for main frames and subframes. |
2698 IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, | 2854 IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, |
2699 FrameNavigationEntry_SequenceNumbers) { | 2855 FrameNavigationEntry_SequenceNumbers) { |
2700 const NavigationControllerImpl& controller = | 2856 const NavigationControllerImpl& controller = |
2701 static_cast<const NavigationControllerImpl&>( | 2857 static_cast<const NavigationControllerImpl&>( |
2702 shell()->web_contents()->GetController()); | 2858 shell()->web_contents()->GetController()); |
2703 | 2859 |
2704 // 1. Navigate the main frame. | 2860 // 1. Navigate the main frame. |
2705 GURL url(embedded_test_server()->GetURL( | 2861 GURL url(embedded_test_server()->GetURL( |
(...skipping 995 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3701 // TODO(clamy): Check the post id as well when PlzNavigate handles it | 3857 // TODO(clamy): Check the post id as well when PlzNavigate handles it |
3702 // properly. | 3858 // properly. |
3703 if (!IsBrowserSideNavigationEnabled()) | 3859 if (!IsBrowserSideNavigationEnabled()) |
3704 EXPECT_NE(-1, frame_entry->post_id()); | 3860 EXPECT_NE(-1, frame_entry->post_id()); |
3705 EXPECT_FALSE(entry->GetHasPostData()); | 3861 EXPECT_FALSE(entry->GetHasPostData()); |
3706 EXPECT_EQ(-1, entry->GetPostID()); | 3862 EXPECT_EQ(-1, entry->GetPostID()); |
3707 } | 3863 } |
3708 } | 3864 } |
3709 | 3865 |
3710 } // namespace content | 3866 } // namespace content |
OLD | NEW |