| 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 5408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5419 // the body of the page. | 5419 // the body of the page. |
| 5420 std::string body; | 5420 std::string body; |
| 5421 EXPECT_TRUE(ExecuteScriptAndExtractString( | 5421 EXPECT_TRUE(ExecuteScriptAndExtractString( |
| 5422 shell()->web_contents(), | 5422 shell()->web_contents(), |
| 5423 "window.domAutomationController.send(" | 5423 "window.domAutomationController.send(" |
| 5424 "document.getElementsByTagName('pre')[0].innerText);", | 5424 "document.getElementsByTagName('pre')[0].innerText);", |
| 5425 &body)); | 5425 &body)); |
| 5426 EXPECT_EQ("text=value\n", body); | 5426 EXPECT_EQ("text=value\n", body); |
| 5427 } | 5427 } |
| 5428 | 5428 |
| 5429 // Tests that inserting a named subframe into the FrameTree clears any |
| 5430 // previously existing FrameNavigationEntry objects for the same name. |
| 5431 // See https://crbug.com/628677. |
| 5432 IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, |
| 5433 EnsureFrameNavigationEntriesClearedOnMismatch) { |
| 5434 WebContentsImpl* web_contents = |
| 5435 static_cast<WebContentsImpl*>(shell()->web_contents()); |
| 5436 NavigationControllerImpl& controller = web_contents->GetController(); |
| 5437 FrameTreeNode* root = web_contents->GetFrameTree()->root(); |
| 5438 |
| 5439 // Start by navigating to a page with complex frame hierarchy. |
| 5440 GURL start_url(embedded_test_server()->GetURL("/frame_tree/top.html")); |
| 5441 EXPECT_TRUE(NavigateToURL(shell(), start_url)); |
| 5442 EXPECT_EQ(3U, root->child_count()); |
| 5443 EXPECT_EQ(2U, root->child_at(0)->child_count()); |
| 5444 |
| 5445 NavigationEntryImpl* entry = controller.GetLastCommittedEntry(); |
| 5446 |
| 5447 // Verify only the parts of the NavigationEntry affected by this test. |
| 5448 { |
| 5449 // * Main frame has 3 subframes. |
| 5450 FrameNavigationEntry* root_entry = entry->GetFrameEntry(root); |
| 5451 EXPECT_NE(nullptr, root_entry); |
| 5452 EXPECT_EQ("", root_entry->frame_unique_name()); |
| 5453 if (SiteIsolationPolicy::UseSubframeNavigationEntries()) { |
| 5454 EXPECT_EQ(3U, entry->root_node()->children.size()); |
| 5455 |
| 5456 // * The first child of the main frame is named and has two more children. |
| 5457 FrameTreeNode* frame = root->child_at(0); |
| 5458 FrameNavigationEntry* frame_entry = entry->GetFrameEntry(frame); |
| 5459 EXPECT_NE(nullptr, frame_entry); |
| 5460 EXPECT_EQ("1-1-name", frame_entry->frame_unique_name()); |
| 5461 EXPECT_EQ(2U, entry->root_node()->children[0]->children.size()); |
| 5462 } |
| 5463 } |
| 5464 |
| 5465 // Removing the first child of the main frame should remove the corresponding |
| 5466 // FrameTreeNode. |
| 5467 std::string remove_frame_script = |
| 5468 "var f = document.getElementById('1-1-id');" |
| 5469 "f.parentNode.removeChild(f);"; |
| 5470 EXPECT_TRUE(ExecuteScript(root, remove_frame_script)); |
| 5471 EXPECT_EQ(2U, root->child_count()); |
| 5472 |
| 5473 // However, the FrameNavigationEntry objects for the frame that was removed |
| 5474 // should still be around. |
| 5475 { |
| 5476 FrameNavigationEntry* root_entry = entry->GetFrameEntry(root); |
| 5477 EXPECT_NE(nullptr, root_entry); |
| 5478 if (SiteIsolationPolicy::UseSubframeNavigationEntries()) { |
| 5479 EXPECT_EQ(3U, entry->root_node()->children.size()); |
| 5480 EXPECT_EQ(2U, entry->root_node()->children[0]->children.size()); |
| 5481 } |
| 5482 } |
| 5483 |
| 5484 // Now, insert a frame with the same name as the previously removed one |
| 5485 // at a different layer of the frame tree. |
| 5486 FrameTreeNode* subframe = root->child_at(1)->child_at(1)->child_at(0); |
| 5487 EXPECT_EQ(2U, root->child_at(1)->child_count()); |
| 5488 EXPECT_EQ(0U, subframe->child_count()); |
| 5489 std::string add_named_frame_script = |
| 5490 "var f = document.createElement('iframe');" |
| 5491 "f.name = '1-1-name';" |
| 5492 "document.body.appendChild(f);"; |
| 5493 EXPECT_TRUE(ExecuteScript(subframe, add_named_frame_script)); |
| 5494 EXPECT_EQ(1U, subframe->child_count()); |
| 5495 |
| 5496 // Verify that the FrameNavigationEntry for the original frame is now gone. |
| 5497 { |
| 5498 FrameNavigationEntry* root_entry = entry->GetFrameEntry(root); |
| 5499 EXPECT_NE(nullptr, root_entry); |
| 5500 if (SiteIsolationPolicy::UseSubframeNavigationEntries()) { |
| 5501 EXPECT_EQ(2U, entry->root_node()->children.size()); |
| 5502 } |
| 5503 } |
| 5504 } |
| 5505 |
| 5506 // Tests that sending a PageState update from a named subframe does not get |
| 5507 // incorrectly set on previously existing FrameNavigationEntry for the same |
| 5508 // name. It is similar to EnsureFrameNavigationEntriesClearedOnConflict, but |
| 5509 // doesn't navigate the iframes to real URLs when added to the DOM. |
| 5510 // See https://crbug.com/628677. |
| 5511 IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, |
| 5512 EnsureFrameNavigationEntriesClearedOnMismatchNoSrc) { |
| 5513 WebContentsImpl* web_contents = |
| 5514 static_cast<WebContentsImpl*>(shell()->web_contents()); |
| 5515 FrameTreeNode* root = web_contents->GetFrameTree()->root(); |
| 5516 |
| 5517 GURL start_url(embedded_test_server()->GetURL("/title1.html")); |
| 5518 EXPECT_TRUE(NavigateToURL(shell(), start_url)); |
| 5519 NavigationEntryImpl* nav_entry = |
| 5520 web_contents->GetController().GetLastCommittedEntry(); |
| 5521 |
| 5522 std::string add_named_frame_script = |
| 5523 "var f = document.createElement('iframe');" |
| 5524 "f.name = 'foo';" |
| 5525 "document.body.appendChild(f);"; |
| 5526 EXPECT_TRUE(ExecuteScript(root, add_named_frame_script)); |
| 5527 EXPECT_EQ(1U, root->child_count()); |
| 5528 EXPECT_EQ("foo", root->child_at(0)->frame_name()); |
| 5529 |
| 5530 std::string remove_frame_script = |
| 5531 "var f = document.querySelector('iframe');" |
| 5532 "f.parentNode.removeChild(f);"; |
| 5533 EXPECT_TRUE(ExecuteScript(root, remove_frame_script)); |
| 5534 EXPECT_EQ(0U, root->child_count()); |
| 5535 |
| 5536 // When a frame is removed from the page, the corresponding |
| 5537 // FrameNavigationEntry is not removed. This is done intentionally to support |
| 5538 // back-forward navigations in subframes and more intuitive UX on tab restore. |
| 5539 if (SiteIsolationPolicy::UseSubframeNavigationEntries()) { |
| 5540 EXPECT_EQ(1U, nav_entry->root_node()->children.size()); |
| 5541 FrameNavigationEntry* frame_entry = |
| 5542 nav_entry->root_node()->children[0]->frame_entry.get(); |
| 5543 EXPECT_EQ("foo", frame_entry->frame_unique_name()); |
| 5544 } |
| 5545 |
| 5546 std::string add_frame_script = |
| 5547 "var f = document.createElement('iframe');" |
| 5548 "document.body.appendChild(f);"; |
| 5549 EXPECT_TRUE(ExecuteScript(root, add_frame_script)); |
| 5550 EXPECT_EQ(1U, root->child_count()); |
| 5551 EXPECT_NE("foo", root->child_at(0)->frame_name()); |
| 5552 |
| 5553 // Add a nested frame with the previously used name. |
| 5554 EXPECT_TRUE(ExecuteScript(root->child_at(0), add_named_frame_script)); |
| 5555 EXPECT_EQ(1U, root->child_at(0)->child_count()); |
| 5556 EXPECT_EQ("foo", root->child_at(0)->child_at(0)->frame_name()); |
| 5557 |
| 5558 if (SiteIsolationPolicy::UseSubframeNavigationEntries()) { |
| 5559 EXPECT_EQ(1U, nav_entry->root_node()->children.size()); |
| 5560 |
| 5561 NavigationEntryImpl::TreeNode* tree_node = |
| 5562 nav_entry->root_node()->children[0]; |
| 5563 EXPECT_EQ(1U, tree_node->children.size()); |
| 5564 |
| 5565 tree_node = tree_node->children[0]; |
| 5566 EXPECT_EQ(0U, tree_node->children.size()); |
| 5567 EXPECT_EQ("foo", tree_node->frame_entry->frame_unique_name()); |
| 5568 } |
| 5569 |
| 5570 EXPECT_TRUE(ExecuteScript(root->child_at(0), remove_frame_script)); |
| 5571 EXPECT_EQ(0U, root->child_at(0)->child_count()); |
| 5572 } |
| 5573 |
| 5429 } // namespace content | 5574 } // namespace content |
| OLD | NEW |