Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(549)

Side by Side Diff: content/browser/site_per_process_browsertest.cc

Issue 1423053002: Make document.activeElement work with OOPIF (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@focus-preserve-page-focus-on-subframe-navigations
Patch Set: Remove some plumbing that should instead be introduced in the window.focus() CL. Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/site_per_process_browsertest.h" 5 #include "content/browser/site_per_process_browsertest.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 const std::string& name) { 90 const std::string& name) {
91 bool success = false; 91 bool success = false;
92 EXPECT_TRUE(ExecuteScriptAndExtractBool( 92 EXPECT_TRUE(ExecuteScriptAndExtractBool(
93 caller_frame, 93 caller_frame,
94 "window.domAutomationController.send(" 94 "window.domAutomationController.send("
95 " !!window.open('" + url.spec() + "', '" + name + "'));", 95 " !!window.open('" + url.spec() + "', '" + name + "'));",
96 &success)); 96 &success));
97 EXPECT_TRUE(success); 97 EXPECT_TRUE(success);
98 } 98 }
99 99
100 // Helper function to generate a click on the given RenderWidgetHost. The
101 // mouse event is forwarded directly to the RenderWidgetHost without any
102 // hit-testing.
103 void SimulateMouseClick(RenderWidgetHost* rwh, int x, int y) {
104 blink::WebMouseEvent mouse_event;
105 mouse_event.type = blink::WebInputEvent::MouseDown;
106 mouse_event.button = blink::WebPointerProperties::ButtonLeft;
107 mouse_event.x = x;
108 mouse_event.y = y;
109 rwh->ForwardMouseEvent(mouse_event);
110 }
111
100 class RedirectNotificationObserver : public NotificationObserver { 112 class RedirectNotificationObserver : public NotificationObserver {
101 public: 113 public:
102 // Register to listen for notifications of the given type from either a 114 // Register to listen for notifications of the given type from either a
103 // specific source, or from all sources if |source| is 115 // specific source, or from all sources if |source| is
104 // NotificationService::AllSources(). 116 // NotificationService::AllSources().
105 RedirectNotificationObserver(int notification_type, 117 RedirectNotificationObserver(int notification_type,
106 const NotificationSource& source); 118 const NotificationSource& source);
107 ~RedirectNotificationObserver() override; 119 ~RedirectNotificationObserver() override;
108 120
109 // Wait until the specified notification occurs. If the notification was 121 // Wait until the specified notification occurs. If the notification was
(...skipping 3536 matching lines...) Expand 10 before | Expand all | Expand 10 after
3646 EXPECT_TRUE(ExecuteScriptAndExtractString(shell()->web_contents(), 3658 EXPECT_TRUE(ExecuteScriptAndExtractString(shell()->web_contents(),
3647 "focusInputField()", &result)); 3659 "focusInputField()", &result));
3648 EXPECT_EQ(result, "input-focus"); 3660 EXPECT_EQ(result, "input-focus");
3649 3661
3650 // The main frame should be focused. 3662 // The main frame should be focused.
3651 EXPECT_EQ(root, root->frame_tree()->GetFocusedFrame()); 3663 EXPECT_EQ(root, root->frame_tree()->GetFocusedFrame());
3652 3664
3653 DOMMessageQueue msg_queue; 3665 DOMMessageQueue msg_queue;
3654 3666
3655 // Click on the cross-process subframe. 3667 // Click on the cross-process subframe.
3656 blink::WebMouseEvent mouse_event; 3668 SimulateMouseClick(
3657 mouse_event.type = blink::WebInputEvent::MouseDown; 3669 root->child_at(0)->current_frame_host()->GetRenderWidgetHost(), 1, 1);
3658 mouse_event.button = blink::WebPointerProperties::ButtonLeft;
3659 mouse_event.x = 1;
3660 mouse_event.y = 1;
3661 RenderWidgetHost* rwh_child =
3662 root->child_at(0)->current_frame_host()->GetRenderWidgetHost();
3663 rwh_child->ForwardMouseEvent(mouse_event);
3664 3670
3665 // Check that the main frame lost focus and fired blur event on the input 3671 // Check that the main frame lost focus and fired blur event on the input
3666 // text field. 3672 // text field.
3667 std::string status; 3673 std::string status;
3668 while (msg_queue.WaitForMessage(&status)) { 3674 while (msg_queue.WaitForMessage(&status)) {
3669 if (status == "\"input-blur\"") 3675 if (status == "\"input-blur\"")
3670 break; 3676 break;
3671 } 3677 }
3672 3678
3673 // The subframe should now be focused. 3679 // The subframe should now be focused.
3674 EXPECT_EQ(root->child_at(0), root->frame_tree()->GetFocusedFrame()); 3680 EXPECT_EQ(root->child_at(0), root->frame_tree()->GetFocusedFrame());
3675 3681
3676 // Click on the root frame. 3682 // Click on the root frame.
3677 shell()->web_contents()->GetRenderViewHost()->GetWidget()->ForwardMouseEvent( 3683 SimulateMouseClick(
3678 mouse_event); 3684 shell()->web_contents()->GetRenderViewHost()->GetWidget(), 1, 1);
3679 3685
3680 // Check that the subframe lost focus and fired blur event on its 3686 // Check that the subframe lost focus and fired blur event on its
3681 // document's body. 3687 // document's body.
3682 while (msg_queue.WaitForMessage(&status)) { 3688 while (msg_queue.WaitForMessage(&status)) {
3683 if (status == "\"document-blur\"") 3689 if (status == "\"document-blur\"")
3684 break; 3690 break;
3685 } 3691 }
3686 3692
3687 // The root frame should be focused again. 3693 // The root frame should be focused again.
3688 EXPECT_EQ(root, root->frame_tree()->GetFocusedFrame()); 3694 EXPECT_EQ(root, root->frame_tree()->GetFocusedFrame());
3689 } 3695 }
3690 3696
3697 // Check that when a cross-process subframe is focused, its parent's
3698 // document.activeElement correctly returns the corresponding <iframe> element.
3699 // The test sets up an A-embed-B-embed-C page and shifts focus A->B->A->C,
3700 // checking document.activeElement after each change.
3701 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, DocumentActiveElement) {
3702 GURL main_url(embedded_test_server()->GetURL(
3703 "a.com", "/cross_site_iframe_factory.html?a(b(c))"));
3704 EXPECT_TRUE(NavigateToURL(shell(), main_url));
3705
3706 FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
3707 ->GetFrameTree()
3708 ->root();
3709
3710 EXPECT_EQ(
3711 " Site A ------------ proxies for B C\n"
3712 " +--Site B ------- proxies for A C\n"
3713 " +--Site C -- proxies for A B\n"
3714 "Where A = http://a.com/\n"
3715 " B = http://b.com/\n"
3716 " C = http://c.com/",
3717 DepictFrameTree(root));
3718
3719 FrameTreeNode* child = root->child_at(0);
3720 FrameTreeNode* grandchild = root->child_at(0)->child_at(0);
3721
3722 // The main frame should be focused to start with.
3723 EXPECT_EQ(root, root->frame_tree()->GetFocusedFrame());
3724
3725 DOMMessageQueue msg_queue;
3726
3727 // Register focus and blur events that will send messages when main frame's
3728 // document body gets or loses focus.
3729 std::string setup_focus_events =
3730 "document.body.onfocus = function() { "
3731 " domAutomationController.setAutomationId(0);"
3732 " domAutomationController.send('got-focus');"
3733 "};"
3734 "document.body.onblur = function() { "
3735 " domAutomationController.setAutomationId(0);"
3736 " domAutomationController.send('lost-focus');"
3737 "};";
3738 EXPECT_TRUE(ExecuteScript(shell()->web_contents(), setup_focus_events));
3739
3740 // Click on the b.com frame.
3741 SimulateMouseClick(child->current_frame_host()->GetRenderWidgetHost(), 1, 1);
3742
3743 // Wait for the main frame to lose focus and fire a blur event on its
3744 // document body.
3745 std::string status;
3746 while (msg_queue.WaitForMessage(&status)) {
3747 if (status == "\"lost-focus\"")
3748 break;
3749 }
3750
3751 // The b.com frame should now be focused.
3752 EXPECT_EQ(child, root->frame_tree()->GetFocusedFrame());
3753
3754 // Helper function to check a property of document.activeElement in the main
3755 // frame.
3756 auto verify_active_element_property = [](RenderFrameHost* rfh,
3757 const std::string& property,
3758 const std::string& expected_value) {
3759 std::string script = base::StringPrintf(
3760 "window.domAutomationController.send(document.activeElement.%s);",
3761 property.c_str());
3762 std::string result;
3763 EXPECT_TRUE(ExecuteScriptAndExtractString(rfh, script, &result));
3764 EXPECT_EQ(expected_value, base::ToLowerASCII(result));
3765 };
3766
3767 // Verify that document.activeElement points to the <iframe> element for the
3768 // b.com frame.
3769 RenderFrameHost* root_rfh = root->current_frame_host();
3770 verify_active_element_property(root_rfh, "tagName", "iframe");
3771 verify_active_element_property(root_rfh, "src", child->current_url().spec());
3772
3773 // Click on the main frame and wait for it to be focused again.
3774 SimulateMouseClick(
3775 shell()->web_contents()->GetRenderViewHost()->GetWidget(), 1, 1);
3776 while (msg_queue.WaitForMessage(&status)) {
3777 if (status == "\"got-focus\"")
3778 break;
3779 }
3780 EXPECT_EQ(root, root->frame_tree()->GetFocusedFrame());
3781
3782 // Main frame document's <body> should now be the active element.
3783 verify_active_element_property(root_rfh, "tagName", "body");
3784
3785 // Click on the grandchild frame to focus it.
3786 SimulateMouseClick(
3787 grandchild->current_frame_host()->GetRenderWidgetHost(), 1, 1);
3788
3789 // Wait for main frame to lose focus.
3790 while (msg_queue.WaitForMessage(&status)) {
3791 if (status == "\"lost-focus\"")
3792 break;
3793 }
3794
3795 // Check document.activeElement in main frame. It should still point to
3796 // <iframe> for the b.com frame, since Blink computes the focused iframe
3797 // element by walking the parent chain of the focused frame until it hits the
3798 // current frame. This logic should still work with remote frames.
3799 verify_active_element_property(root_rfh, "tagName", "iframe");
3800 verify_active_element_property(root_rfh, "src", child->current_url().spec());
3801
3802 // Check document.activeElement in b.com subframe. It should point to
3803 // <iframe> for the c.com frame. This is a tricky case where B needs to find
3804 // out that focus changed from one remote frame to another (A to C).
3805 RenderFrameHost* child_rfh = child->current_frame_host();
3806 verify_active_element_property(child_rfh, "tagName", "iframe");
3807 verify_active_element_property(child_rfh, "src",
3808 grandchild->current_url().spec());
3809 }
3810
3691 // There are no cursors on Android. 3811 // There are no cursors on Android.
3692 #if !defined(OS_ANDROID) 3812 #if !defined(OS_ANDROID)
3693 class CursorMessageFilter : public content::BrowserMessageFilter { 3813 class CursorMessageFilter : public content::BrowserMessageFilter {
3694 public: 3814 public:
3695 CursorMessageFilter() 3815 CursorMessageFilter()
3696 : content::BrowserMessageFilter(ViewMsgStart), 3816 : content::BrowserMessageFilter(ViewMsgStart),
3697 message_loop_runner_(new content::MessageLoopRunner), 3817 message_loop_runner_(new content::MessageLoopRunner),
3698 last_set_cursor_routing_id_(MSG_ROUTING_NONE) {} 3818 last_set_cursor_routing_id_(MSG_ROUTING_NONE) {}
3699 3819
3700 bool OnMessageReceived(const IPC::Message& message) override { 3820 bool OnMessageReceived(const IPC::Message& message) override {
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
3785 3905
3786 // Use new window to navigate main window. 3906 // Use new window to navigate main window.
3787 std::string script = 3907 std::string script =
3788 "window.opener.location.href = '" + cross_url.spec() + "'"; 3908 "window.opener.location.href = '" + cross_url.spec() + "'";
3789 EXPECT_TRUE(ExecuteScript(popup->web_contents(), script)); 3909 EXPECT_TRUE(ExecuteScript(popup->web_contents(), script));
3790 EXPECT_TRUE(WaitForLoadStop(shell()->web_contents())); 3910 EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
3791 EXPECT_EQ(shell()->web_contents()->GetLastCommittedURL(), cross_url); 3911 EXPECT_EQ(shell()->web_contents()->GetLastCommittedURL(), cross_url);
3792 } 3912 }
3793 3913
3794 } // namespace content 3914 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698