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

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: 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 3371 matching lines...) Expand 10 before | Expand all | Expand 10 after
3481 EXPECT_TRUE(ExecuteScriptAndExtractString(shell()->web_contents(), 3493 EXPECT_TRUE(ExecuteScriptAndExtractString(shell()->web_contents(),
3482 "focusInputField()", &result)); 3494 "focusInputField()", &result));
3483 EXPECT_EQ(result, "input-focus"); 3495 EXPECT_EQ(result, "input-focus");
3484 3496
3485 // The main frame should be focused. 3497 // The main frame should be focused.
3486 EXPECT_EQ(root, root->frame_tree()->GetFocusedFrame()); 3498 EXPECT_EQ(root, root->frame_tree()->GetFocusedFrame());
3487 3499
3488 DOMMessageQueue msg_queue; 3500 DOMMessageQueue msg_queue;
3489 3501
3490 // Click on the cross-process subframe. 3502 // Click on the cross-process subframe.
3491 blink::WebMouseEvent mouse_event; 3503 SimulateMouseClick(
3492 mouse_event.type = blink::WebInputEvent::MouseDown; 3504 root->child_at(0)->current_frame_host()->GetRenderWidgetHost(), 1, 1);
3493 mouse_event.button = blink::WebPointerProperties::ButtonLeft;
3494 mouse_event.x = 1;
3495 mouse_event.y = 1;
3496 RenderWidgetHost* rwh_child =
3497 root->child_at(0)->current_frame_host()->GetRenderWidgetHost();
3498 rwh_child->ForwardMouseEvent(mouse_event);
3499 3505
3500 // Check that the main frame lost focus and fired blur event on the input 3506 // Check that the main frame lost focus and fired blur event on the input
3501 // text field. 3507 // text field.
3502 std::string status; 3508 std::string status;
3503 while (msg_queue.WaitForMessage(&status)) { 3509 while (msg_queue.WaitForMessage(&status)) {
3504 if (status == "\"input-blur\"") 3510 if (status == "\"input-blur\"")
3505 break; 3511 break;
3506 } 3512 }
3507 3513
3508 // The subframe should now be focused. 3514 // The subframe should now be focused.
3509 EXPECT_EQ(root->child_at(0), root->frame_tree()->GetFocusedFrame()); 3515 EXPECT_EQ(root->child_at(0), root->frame_tree()->GetFocusedFrame());
3510 3516
3511 // Click on the root frame. 3517 // Click on the root frame.
3512 shell()->web_contents()->GetRenderViewHost()->GetWidget()->ForwardMouseEvent( 3518 SimulateMouseClick(
3513 mouse_event); 3519 shell()->web_contents()->GetRenderViewHost()->GetWidget(), 1, 1);
3514 3520
3515 // Check that the subframe lost focus and fired blur event on its 3521 // Check that the subframe lost focus and fired blur event on its
3516 // document's body. 3522 // document's body.
3517 while (msg_queue.WaitForMessage(&status)) { 3523 while (msg_queue.WaitForMessage(&status)) {
3518 if (status == "\"document-blur\"") 3524 if (status == "\"document-blur\"")
3519 break; 3525 break;
3520 } 3526 }
3521 3527
3522 // The root frame should be focused again. 3528 // The root frame should be focused again.
3523 EXPECT_EQ(root, root->frame_tree()->GetFocusedFrame()); 3529 EXPECT_EQ(root, root->frame_tree()->GetFocusedFrame());
3524 } 3530 }
3525 3531
3532 // Check that when a cross-process subframe is focused, its parent's
3533 // document.activeElement correctly returns the corresponding <iframe> element.
3534 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, DocumentActiveElement) {
3535 GURL main_url(embedded_test_server()->GetURL(
3536 "a.com", "/cross_site_iframe_factory.html?a(b(c))"));
3537 EXPECT_TRUE(NavigateToURL(shell(), main_url));
3538
3539 FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
3540 ->GetFrameTree()
3541 ->root();
3542
3543 EXPECT_EQ(
3544 " Site A ------------ proxies for B C\n"
3545 " +--Site B ------- proxies for A C\n"
3546 " +--Site C -- proxies for A B\n"
3547 "Where A = http://a.com/\n"
3548 " B = http://b.com/\n"
3549 " C = http://c.com/",
3550 DepictFrameTree(root));
3551
3552 FrameTreeNode* child = root->child_at(0);
3553 FrameTreeNode* grandchild = root->child_at(0)->child_at(0);
3554
3555 // The main frame should be focused to start with.
3556 EXPECT_EQ(root, root->frame_tree()->GetFocusedFrame());
3557
3558 DOMMessageQueue msg_queue;
3559
3560 // Register focus and blur events that will send messages when main frame's
3561 // document body gets or loses focus.
3562 std::string setup_focus_events =
3563 "document.body.onfocus = function() { "
3564 " domAutomationController.setAutomationId(0);"
3565 " domAutomationController.send('got-focus');"
3566 "};"
3567 "document.body.onblur = function() { "
3568 " domAutomationController.setAutomationId(0);"
3569 " domAutomationController.send('lost-focus');"
3570 "};";
3571 EXPECT_TRUE(
3572 content::ExecuteScript(shell()->web_contents(), setup_focus_events));
3573
3574 // Click on the b.com frame.
3575 SimulateMouseClick(child->current_frame_host()->GetRenderWidgetHost(), 1, 1);
3576
3577 // Wait for the main frame to lose focus and fire a blur event on its
3578 // document body.
3579 std::string status;
3580 while (msg_queue.WaitForMessage(&status)) {
3581 if (status == "\"lost-focus\"")
3582 break;
3583 }
3584
3585 // The b.com frame should now be focused.
3586 EXPECT_EQ(child, root->frame_tree()->GetFocusedFrame());
3587
3588 // Helper function to check a property of document.activeElement in the main
3589 // frame.
3590 auto verify_active_element_property = [this](
3591 const std::string& property, const std::string& expected_value) {
3592 std::string script = base::StringPrintf(
3593 "window.domAutomationController.send(document.activeElement.%s);",
3594 property.c_str());
3595 std::string result;
3596 EXPECT_TRUE(ExecuteScriptAndExtractString(shell()->web_contents(),
3597 script, &result));
3598 EXPECT_EQ(expected_value, base::ToLowerASCII(result));
3599 };
3600
3601 // Verify that document.activeElement points to the <iframe> element for the
3602 // b.com frame.
3603 verify_active_element_property("tagName", "iframe");
3604 verify_active_element_property("src", child->current_url().spec());
3605
3606 // Click on the main frame and wait for it to be focused again.
3607 SimulateMouseClick(
3608 shell()->web_contents()->GetRenderViewHost()->GetWidget(), 1, 1);
3609 while (msg_queue.WaitForMessage(&status)) {
3610 if (status == "\"got-focus\"")
3611 break;
3612 }
3613 EXPECT_EQ(root, root->frame_tree()->GetFocusedFrame());
3614
3615 // Main frame document's <body> should now be the active element.
3616 verify_active_element_property("tagName", "body");
3617
3618 // Click on the grandchild frame to focus it.
3619 SimulateMouseClick(
3620 grandchild->current_frame_host()->GetRenderWidgetHost(), 1, 1);
3621
3622 // Wait for main frame to lose focus.
3623 while (msg_queue.WaitForMessage(&status)) {
3624 if (status == "\"lost-focus\"")
3625 break;
3626 }
3627
3628 // Check document.activeElement in main frame. It should still point to
3629 // <iframe> for the b.com frame, since Blink computes the focused iframe
3630 // element by walking the parent chain of the focused frame until it hits the
3631 // current frame. This logic should still work with remote frames.
3632 verify_active_element_property("tagName", "iframe");
3633 verify_active_element_property("src", child->current_url().spec());
3634 }
3635
3526 // There are no cursors on Android. 3636 // There are no cursors on Android.
3527 #if !defined(OS_ANDROID) 3637 #if !defined(OS_ANDROID)
3528 class CursorMessageFilter : public content::BrowserMessageFilter { 3638 class CursorMessageFilter : public content::BrowserMessageFilter {
3529 public: 3639 public:
3530 CursorMessageFilter() 3640 CursorMessageFilter()
3531 : content::BrowserMessageFilter(ViewMsgStart), 3641 : content::BrowserMessageFilter(ViewMsgStart),
3532 message_loop_runner_(new content::MessageLoopRunner), 3642 message_loop_runner_(new content::MessageLoopRunner),
3533 last_set_cursor_routing_id_(MSG_ROUTING_NONE) {} 3643 last_set_cursor_routing_id_(MSG_ROUTING_NONE) {}
3534 3644
3535 bool OnMessageReceived(const IPC::Message& message) override { 3645 bool OnMessageReceived(const IPC::Message& message) override {
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
3620 3730
3621 // Use new window to navigate main window. 3731 // Use new window to navigate main window.
3622 std::string script = 3732 std::string script =
3623 "window.opener.location.href = '" + cross_url.spec() + "'"; 3733 "window.opener.location.href = '" + cross_url.spec() + "'";
3624 EXPECT_TRUE(ExecuteScript(popup->web_contents(), script)); 3734 EXPECT_TRUE(ExecuteScript(popup->web_contents(), script));
3625 EXPECT_TRUE(WaitForLoadStop(shell()->web_contents())); 3735 EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
3626 EXPECT_EQ(shell()->web_contents()->GetLastCommittedURL(), cross_url); 3736 EXPECT_EQ(shell()->web_contents()->GetLastCommittedURL(), cross_url);
3627 } 3737 }
3628 3738
3629 } // namespace content 3739 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698