Skip to content
This repository has been archived by the owner on Apr 3, 2020. It is now read-only.

Commit

Permalink
Make load events in iframe elements work with OOPIF (Chromium side).
Browse files Browse the repository at this point in the history
Today, when the parent frame defines a load event handler in the
iframe element of an out-of-process child frame, the event does not
fire in the parent process.  This CL adds the plumbing to forward the
event from the child frame's process to the parent frame's process.

Blink side: https://codereview.chromium.org/937203003

BUG=453690

Review URL: https://codereview.chromium.org/954793002

Cr-Commit-Position: refs/heads/master@{#318101}
  • Loading branch information
alexmos authored and Commit bot committed Feb 25, 2015
1 parent 2d8afa3 commit f40ce5b
Show file tree
Hide file tree
Showing 9 changed files with 79 additions and 0 deletions.
16 changes: 16 additions & 0 deletions content/browser/frame_host/render_frame_host_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,7 @@ bool RenderFrameHostImpl::OnMessageReceived(const IPC::Message &msg) {
IPC_MESSAGE_HANDLER(FrameHostMsg_UpdateEncoding, OnUpdateEncoding)
IPC_MESSAGE_HANDLER(FrameHostMsg_BeginNavigation,
OnBeginNavigation)
IPC_MESSAGE_HANDLER(FrameHostMsg_DispatchLoad, OnDispatchLoad)
IPC_MESSAGE_HANDLER(FrameHostMsg_TextSurroundingSelectionResponse,
OnTextSurroundingSelectionResponse)
IPC_MESSAGE_HANDLER(AccessibilityHostMsg_Events, OnAccessibilityEvents)
Expand Down Expand Up @@ -1223,6 +1224,21 @@ void RenderFrameHostImpl::OnBeginNavigation(
frame_tree_node(), common_params, begin_params, body);
}

void RenderFrameHostImpl::OnDispatchLoad() {
CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kSitePerProcess));
// Only frames with an out-of-process parent frame should be sending this
// message.
RenderFrameProxyHost* proxy =
frame_tree_node()->render_manager()->GetProxyToParent();
if (!proxy) {
GetProcess()->ReceivedBadMessage();
return;
}

proxy->Send(new FrameMsg_DispatchLoad(proxy->GetRoutingID()));
}

void RenderFrameHostImpl::OnAccessibilityEvents(
const std::vector<AccessibilityHostMsg_EventParams>& params,
int reset_token) {
Expand Down
1 change: 1 addition & 0 deletions content/browser/frame_host/render_frame_host_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,7 @@ class CONTENT_EXPORT RenderFrameHostImpl
void OnBeginNavigation(const CommonNavigationParams& common_params,
const BeginNavigationParams& begin_params,
scoped_refptr<ResourceRequestBody> body);
void OnDispatchLoad();
void OnAccessibilityEvents(
const std::vector<AccessibilityHostMsg_EventParams>& params,
int reset_token);
Expand Down
34 changes: 34 additions & 0 deletions content/browser/site_per_process_browsertest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1353,4 +1353,38 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
EXPECT_TRUE(node3->current_frame_host()->IsRenderFrameLive());
}

// Verify that load events for iframe elements work when the child frame is
// out-of-process. In such cases, the load event is forwarded from the child
// frame to the parent frame via the browser process.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, LoadEventForwarding) {
// Load a page with a cross-site frame. The parent page has an onload
// handler in the iframe element that appends "LOADED" to the document title.
{
GURL main_url(
embedded_test_server()->GetURL("/frame_with_load_event.html"));
base::string16 expected_title(base::UTF8ToUTF16("LOADED"));
TitleWatcher title_watcher(shell()->web_contents(), expected_title);
EXPECT_TRUE(NavigateToURL(shell(), main_url));
EXPECT_EQ(title_watcher.WaitAndGetTitle(), expected_title);
}

// It is safe to obtain the root frame tree node here, as it doesn't change.
FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
->GetFrameTree()
->root();

// Load another cross-site page into the iframe and check that the load event
// is fired.
{
GURL foo_url(embedded_test_server()->GetURL("foo.com", "/title1.html"));
base::string16 expected_title(base::UTF8ToUTF16("LOADEDLOADED"));
TitleWatcher title_watcher(shell()->web_contents(), expected_title);
TestNavigationObserver observer(shell()->web_contents());
NavigateFrameToURL(root->child_at(0), foo_url);
EXPECT_TRUE(observer.last_navigation_succeeded());
EXPECT_EQ(foo_url, observer.last_navigation_url());
EXPECT_EQ(title_watcher.WaitAndGetTitle(), expected_title);
}
}

} // namespace content
7 changes: 7 additions & 0 deletions content/common/frame_messages.h
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,9 @@ IPC_MESSAGE_ROUTED1(FrameMsg_AddStyleSheetByURL, std::string)
IPC_MESSAGE_ROUTED1(FrameMsg_SetAccessibilityMode,
AccessibilityMode)

// Dispatch a load event in the iframe element containing this frame.
IPC_MESSAGE_ROUTED0(FrameMsg_DispatchLoad)

#if defined(OS_ANDROID)

// External popup menus.
Expand Down Expand Up @@ -861,6 +864,10 @@ IPC_MESSAGE_ROUTED1(FrameHostMsg_BeforeUnloadHandlersPresent,
IPC_MESSAGE_ROUTED1(FrameHostMsg_UnloadHandlersPresent,
bool /* present */)

// Dispatch a load event for this frame in the iframe element of an
// out-of-process parent frame.
IPC_MESSAGE_ROUTED0(FrameHostMsg_DispatchLoad)

#if defined(OS_MACOSX) || defined(OS_ANDROID)

// Message to show/hide a popup menu using native controls.
Expand Down
4 changes: 4 additions & 0 deletions content/renderer/render_frame_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2768,6 +2768,10 @@ void RenderFrameImpl::didChangeThemeColor() {
routing_id_, frame_->document().themeColor()));
}

void RenderFrameImpl::dispatchLoad() {
Send(new FrameHostMsg_DispatchLoad(routing_id_));
}

void RenderFrameImpl::requestNotificationPermission(
const blink::WebSecurityOrigin& origin,
blink::WebNotificationPermissionCallback* callback) {
Expand Down
1 change: 1 addition & 0 deletions content/renderer/render_frame_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,7 @@ class CONTENT_EXPORT RenderFrameImpl
virtual void addNavigationTransitionData(
const blink::WebTransitionElementData& data);
virtual void didChangeThemeColor();
virtual void dispatchLoad();
virtual void requestNotificationPermission(
const blink::WebSecurityOrigin& origin,
blink::WebNotificationPermissionCallback* callback);
Expand Down
5 changes: 5 additions & 0 deletions content/renderer/render_frame_proxy.cc
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ bool RenderFrameProxy::OnMessageReceived(const IPC::Message& msg) {
IPC_MESSAGE_HANDLER(FrameMsg_DisownOpener, OnDisownOpener)
IPC_MESSAGE_HANDLER(FrameMsg_DidStartLoading, OnDidStartLoading)
IPC_MESSAGE_HANDLER(FrameMsg_DidStopLoading, OnDidStopLoading)
IPC_MESSAGE_HANDLER(FrameMsg_DispatchLoad, OnDispatchLoad)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()

Expand Down Expand Up @@ -262,6 +263,10 @@ void RenderFrameProxy::OnDidStopLoading() {
web_frame_->didStopLoading();
}

void RenderFrameProxy::OnDispatchLoad() {
web_frame_->DispatchLoadEventForFrameOwner();
}

void RenderFrameProxy::frameDetached() {
if (web_frame_->parent())
web_frame_->parent()->removeChild(web_frame_);
Expand Down
1 change: 1 addition & 0 deletions content/renderer/render_frame_proxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ class CONTENT_EXPORT RenderFrameProxy
void OnCompositorFrameSwapped(const IPC::Message& message);
void OnDisownOpener();
void OnDidStopLoading();
void OnDispatchLoad();

// The routing ID by which this RenderFrameProxy is known.
const int routing_id_;
Expand Down
10 changes: 10 additions & 0 deletions content/test/data/frame_with_load_event.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
</head>
<body>
This page has a cross-site iframe with a load event.
<iframe id='test' onload="document.title += 'LOADED';" src="/cross-site/baz.com/title1.html"></iframe>
</body>
</html>

0 comments on commit f40ce5b

Please sign in to comment.