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 3023 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3034 EXPECT_EQ(1, controller.GetLastCommittedEntryIndex()); | 3034 EXPECT_EQ(1, controller.GetLastCommittedEntryIndex()); |
3035 EXPECT_EQ(entry2, controller.GetLastCommittedEntry()); | 3035 EXPECT_EQ(entry2, controller.GetLastCommittedEntry()); |
3036 | 3036 |
3037 // The entry should have both the stale FrameNavigationEntry with the old | 3037 // The entry should have both the stale FrameNavigationEntry with the old |
3038 // name and the new FrameNavigationEntry for the fallback navigation. | 3038 // name and the new FrameNavigationEntry for the fallback navigation. |
3039 ASSERT_EQ(2U, entry2->root_node()->children.size()); | 3039 ASSERT_EQ(2U, entry2->root_node()->children.size()); |
3040 EXPECT_EQ(frame_url_b, entry2->root_node()->children[0]->frame_entry->url()); | 3040 EXPECT_EQ(frame_url_b, entry2->root_node()->children[0]->frame_entry->url()); |
3041 EXPECT_EQ(data_url, entry2->root_node()->children[1]->frame_entry->url()); | 3041 EXPECT_EQ(data_url, entry2->root_node()->children[1]->frame_entry->url()); |
3042 } | 3042 } |
3043 | 3043 |
3044 // Allows waiting until an URL with a data scheme commits in any frame. | |
3045 class DataUrlCommitObserver : public WebContentsObserver { | |
3046 public: | |
3047 explicit DataUrlCommitObserver(WebContents* web_contents) | |
3048 : WebContentsObserver(web_contents), | |
3049 message_loop_runner_(new MessageLoopRunner) {} | |
3050 | |
3051 void Wait() { message_loop_runner_->Run(); } | |
3052 | |
3053 private: | |
3054 void DidFinishNavigation(NavigationHandle* navigation_handle) override { | |
3055 if (navigation_handle->HasCommitted() && | |
3056 !navigation_handle->IsErrorPage() && | |
3057 navigation_handle->GetURL().scheme() == "data") | |
3058 message_loop_runner_->Quit(); | |
3059 } | |
3060 | |
3061 // The MessageLoopRunner used to spin the message loop. | |
3062 scoped_refptr<MessageLoopRunner> message_loop_runner_; | |
3063 }; | |
3064 | |
3065 // Verify that dynamically generated iframes load properly during a history | |
3066 // navigation if no history item can be found for them. | |
3067 // See https://crbug.com/649345. | |
3068 IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, | |
3069 FrameNavigationEntry_DynamicSubframeHistoryFallback) { | |
3070 // This test only makes sense when subframe FrameNavigationEntries are in use. | |
3071 if (!SiteIsolationPolicy::UseSubframeNavigationEntries()) | |
3072 return; | |
3073 | |
3074 // 1. Start on a page with a script-generated iframe. The iframe has a | |
3075 // dynamic name, starts at about:blank, and gets navigated to a dynamic data | |
3076 // URL as the page is loading. | |
3077 GURL main_url_a(embedded_test_server()->GetURL( | |
3078 "a.com", "/navigation_controller/dynamic_iframe.html")); | |
3079 { | |
3080 // Wait until the data URL has committed, even if load stop happens after | |
3081 // about:blank load. | |
3082 DataUrlCommitObserver data_observer(shell()->web_contents()); | |
3083 NavigateToURL(shell(), main_url_a); | |
alexmos
2016/09/29 21:55:53
nit: EXPECT_TRUE, also below
Charlie Reis
2016/09/29 22:22:48
D'oh! Done. One day I'll fix the rest of the occ
| |
3084 data_observer.Wait(); | |
3085 } | |
3086 const NavigationControllerImpl& controller = | |
3087 static_cast<const NavigationControllerImpl&>( | |
3088 shell()->web_contents()->GetController()); | |
3089 FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) | |
3090 ->GetFrameTree() | |
3091 ->root(); | |
3092 ASSERT_EQ(1U, root->child_count()); | |
3093 ASSERT_EQ(0U, root->child_at(0)->child_count()); | |
3094 EXPECT_EQ(main_url_a, root->current_url()); | |
3095 EXPECT_EQ("data", root->child_at(0)->current_url().scheme()); | |
3096 | |
3097 EXPECT_EQ(1, controller.GetEntryCount()); | |
3098 EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); | |
3099 NavigationEntryImpl* entry1 = controller.GetLastCommittedEntry(); | |
3100 | |
3101 // The entry should have a FrameNavigationEntry for the data subframe. | |
3102 ASSERT_EQ(1U, entry1->root_node()->children.size()); | |
3103 EXPECT_EQ("data", | |
3104 entry1->root_node()->children[0]->frame_entry->url().scheme()); | |
3105 | |
3106 // 2. Navigate main frame cross-site, destroying the frames. | |
3107 GURL main_url_b(embedded_test_server()->GetURL( | |
3108 "b.com", "/navigation_controller/simple_page_2.html")); | |
3109 NavigateToURL(shell(), main_url_b); | |
3110 ASSERT_EQ(0U, root->child_count()); | |
3111 EXPECT_EQ(main_url_b, root->current_url()); | |
3112 | |
3113 EXPECT_EQ(2, controller.GetEntryCount()); | |
3114 EXPECT_EQ(1, controller.GetLastCommittedEntryIndex()); | |
3115 NavigationEntryImpl* entry2 = controller.GetLastCommittedEntry(); | |
3116 EXPECT_EQ(0U, entry2->root_node()->children.size()); | |
3117 | |
3118 // Force the subframe entry to have the wrong name, so that it isn't found | |
3119 // when we go back. (The page should give it a different name anyway, but | |
3120 // this safeguards against flakiness.) | |
alexmos
2016/09/29 21:55:53
Wow, I'm curious how the flakiness could possibly
Charlie Reis
2016/09/29 22:22:48
It wasn't actually failing for me, but I was tryin
| |
3121 entry1->root_node()->children[0]->frame_entry->set_frame_unique_name("wrong"); | |
3122 | |
3123 // 3. Go back, recreating the iframe. The subframe will have a new name this | |
3124 // time, so we won't find a history item for it. We should let the new data | |
3125 // URL be loaded into it, rather than clobbering it with an about:blank page. | |
3126 { | |
3127 // Wait until the data URL has committed, even if load stop happens first. | |
3128 DataUrlCommitObserver back_load_observer(shell()->web_contents()); | |
3129 shell()->web_contents()->GetController().GoBack(); | |
3130 back_load_observer.Wait(); | |
3131 } | |
3132 EXPECT_TRUE(WaitForLoadStop(shell()->web_contents())); | |
3133 ASSERT_EQ(1U, root->child_count()); | |
3134 EXPECT_EQ(main_url_a, root->current_url()); | |
3135 EXPECT_EQ("data", root->child_at(0)->current_url().scheme()); | |
3136 | |
3137 EXPECT_EQ(2, controller.GetEntryCount()); | |
3138 EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); | |
3139 EXPECT_EQ(entry1, controller.GetLastCommittedEntry()); | |
3140 | |
3141 // The entry should have both the stale FrameNavigationEntry with the old | |
3142 // name and the new FrameNavigationEntry for the fallback navigation. | |
alexmos
2016/09/29 21:55:53
Just curious, why do we need to keep the stale Fra
Charlie Reis
2016/09/29 22:22:48
In general, we don't remove subframe history items
| |
3143 ASSERT_EQ(2U, entry1->root_node()->children.size()); | |
3144 EXPECT_EQ("data", | |
3145 entry1->root_node()->children[0]->frame_entry->url().scheme()); | |
3146 EXPECT_EQ("data", | |
3147 entry1->root_node()->children[1]->frame_entry->url().scheme()); | |
alexmos
2016/09/29 21:55:53
Not that it matters, but you could also double-che
Charlie Reis
2016/09/29 22:22:48
I'll stick with the scheme check, now that I've re
| |
3148 | |
3149 // The iframe commit should have been classified AUTO_SUBFRAME and not | |
3150 // NEW_SUBFRAME, so we should still be able to go forward. | |
3151 EXPECT_TRUE(shell()->web_contents()->GetController().CanGoForward()); | |
3152 } | |
3153 | |
3044 // Verify that we don't clobber any content injected into the initial blank page | 3154 // Verify that we don't clobber any content injected into the initial blank page |
3045 // if we go back to an about:blank subframe. See https://crbug.com/626416. | 3155 // if we go back to an about:blank subframe. See https://crbug.com/626416. |
3046 IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, | 3156 IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, |
3047 FrameNavigationEntry_RecreatedBlankSubframe) { | 3157 FrameNavigationEntry_RecreatedBlankSubframe) { |
3048 // 1. Start on a page that injects content into an about:blank iframe. | 3158 // 1. Start on a page that injects content into an about:blank iframe. |
3049 GURL main_url(embedded_test_server()->GetURL( | 3159 GURL main_url(embedded_test_server()->GetURL( |
3050 "/navigation_controller/inject_into_blank_iframe.html")); | 3160 "/navigation_controller/inject_into_blank_iframe.html")); |
3051 GURL blank_url(url::kAboutBlankURL); | 3161 GURL blank_url(url::kAboutBlankURL); |
3052 EXPECT_TRUE(NavigateToURL(shell(), main_url)); | 3162 EXPECT_TRUE(NavigateToURL(shell(), main_url)); |
3053 NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( | 3163 NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>( |
(...skipping 3174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6228 | 6338 |
6229 // What happens now is that attempting to unload the first page will trigger a | 6339 // What happens now is that attempting to unload the first page will trigger a |
6230 // JavaScript alert but allow navigation. The alert IPC will be suspended by | 6340 // JavaScript alert but allow navigation. The alert IPC will be suspended by |
6231 // the message filter. The commit of the second page will unblock the IPC. If | 6341 // the message filter. The commit of the second page will unblock the IPC. If |
6232 // the dialog IPC is allowed to spawn a dialog, the call by the WebContents to | 6342 // the dialog IPC is allowed to spawn a dialog, the call by the WebContents to |
6233 // its delegate to get the JavaScriptDialogManager will cause a CHECK and the | 6343 // its delegate to get the JavaScriptDialogManager will cause a CHECK and the |
6234 // test will fail. | 6344 // test will fail. |
6235 } | 6345 } |
6236 | 6346 |
6237 } // namespace content | 6347 } // namespace content |
OLD | NEW |