| Index: content/renderer/render_frame_impl.cc
|
| diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
|
| index 88b26d2e20fc7dc1884a675f35c497d2481b4490..703363fbbc7265fbf1673d2b10c12e04152ec599 100644
|
| --- a/content/renderer/render_frame_impl.cc
|
| +++ b/content/renderer/render_frame_impl.cc
|
| @@ -125,6 +125,7 @@
|
| #include "third_party/WebKit/public/web/WebDocument.h"
|
| #include "third_party/WebKit/public/web/WebFrameWidget.h"
|
| #include "third_party/WebKit/public/web/WebGlyphCache.h"
|
| +#include "third_party/WebKit/public/web/WebKit.h"
|
| #include "third_party/WebKit/public/web/WebLocalFrame.h"
|
| #include "third_party/WebKit/public/web/WebMediaStreamRegistry.h"
|
| #include "third_party/WebKit/public/web/WebNavigationPolicy.h"
|
| @@ -137,6 +138,7 @@
|
| #include "third_party/WebKit/public/web/WebSearchableFormData.h"
|
| #include "third_party/WebKit/public/web/WebSecurityOrigin.h"
|
| #include "third_party/WebKit/public/web/WebSecurityPolicy.h"
|
| +#include "third_party/WebKit/public/web/WebSerializedScriptValue.h"
|
| #include "third_party/WebKit/public/web/WebSettings.h"
|
| #include "third_party/WebKit/public/web/WebSurroundingText.h"
|
| #include "third_party/WebKit/public/web/WebUserGestureIndicator.h"
|
| @@ -186,6 +188,8 @@ using blink::WebContextMenuData;
|
| using blink::WebData;
|
| using blink::WebDataSource;
|
| using blink::WebDocument;
|
| +using blink::WebDOMEvent;
|
| +using blink::WebDOMMessageEvent;
|
| using blink::WebElement;
|
| using blink::WebExternalPopupMenu;
|
| using blink::WebExternalPopupMenuClient;
|
| @@ -206,6 +210,7 @@ using blink::WebScriptSource;
|
| using blink::WebSearchableFormData;
|
| using blink::WebSecurityOrigin;
|
| using blink::WebSecurityPolicy;
|
| +using blink::WebSerializedScriptValue;
|
| using blink::WebServiceWorkerProvider;
|
| using blink::WebStorageQuotaCallbacks;
|
| using blink::WebString;
|
| @@ -1049,6 +1054,7 @@ bool RenderFrameImpl::OnMessageReceived(const IPC::Message& msg) {
|
| IPC_MESSAGE_HANDLER(FrameMsg_DidUpdateSandboxFlags, OnDidUpdateSandboxFlags)
|
| IPC_MESSAGE_HANDLER(FrameMsg_SetTextTrackSettings,
|
| OnTextTrackSettingsChanged)
|
| + IPC_MESSAGE_HANDLER(FrameMsg_PostMessageEvent, OnPostMessageEvent)
|
| #if defined(OS_ANDROID)
|
| IPC_MESSAGE_HANDLER(FrameMsg_SelectPopupMenuItems, OnSelectPopupMenuItems)
|
| #elif defined(OS_MACOSX)
|
| @@ -1261,6 +1267,12 @@ void RenderFrameImpl::OnSwapOut(
|
| render_view_->SetSwappedOut(true);
|
| is_swapped_out_ = true;
|
|
|
| + // Set the proxy here, since OnStop() below could cause an onload event
|
| + // handler to execute, which could trigger code such as
|
| + // willCheckAndDispatchMessageEvent() that needs the proxy.
|
| + if (proxy)
|
| + set_render_frame_proxy(proxy);
|
| +
|
| // Now that we're swapped out and filtering IPC messages, stop loading to
|
| // ensure that no other in-progress navigation continues. We do this here
|
| // to avoid sending a DidStopLoading message to the browser process.
|
| @@ -1310,8 +1322,6 @@ void RenderFrameImpl::OnSwapOut(
|
| // TODO(nasko): delete the frame here, since we've replaced it with a
|
| // proxy.
|
| }
|
| - } else {
|
| - set_render_frame_proxy(proxy);
|
| }
|
| }
|
|
|
| @@ -1602,6 +1612,77 @@ void RenderFrameImpl::OnTextTrackSettingsChanged(
|
| WebString::fromUTF8(params.text_track_text_size));
|
| }
|
|
|
| +void RenderFrameImpl::OnPostMessageEvent(
|
| + const FrameMsg_PostMessage_Params& params) {
|
| + // Find the source frame if it exists.
|
| + WebFrame* source_frame = NULL;
|
| + if (params.source_view_routing_id != MSG_ROUTING_NONE) {
|
| + // Support a legacy postMessage path for specifying a source RenderView;
|
| + // this is currently used when sending messages to Android WebView.
|
| + // TODO(alexmos): This path can be removed once crbug.com/473258 is fixed.
|
| + RenderViewImpl* source_view =
|
| + RenderViewImpl::FromRoutingID(params.source_view_routing_id);
|
| + if (source_view)
|
| + source_frame = source_view->webview()->mainFrame();
|
| + } else if (params.source_routing_id != MSG_ROUTING_NONE) {
|
| + RenderFrameProxy* source_proxy =
|
| + RenderFrameProxy::FromRoutingID(params.source_routing_id);
|
| + if (source_proxy) {
|
| + // Currently, navigating a top-level frame cross-process does not swap
|
| + // the WebLocalFrame for a WebRemoteFrame in the frame tree, and the
|
| + // WebRemoteFrame will not have an associated blink::Frame. If this is
|
| + // the case for |source_proxy|, use the corresponding (swapped-out)
|
| + // WebLocalFrame instead, so that event.source for this message can be
|
| + // set and used properly.
|
| + if (source_proxy->IsMainFrameDetachedFromTree())
|
| + source_frame = source_proxy->render_view()->webview()->mainFrame();
|
| + else
|
| + source_frame = source_proxy->web_frame();
|
| + }
|
| + }
|
| +
|
| + // If the message contained MessagePorts, create the corresponding endpoints.
|
| + blink::WebMessagePortChannelArray channels =
|
| + WebMessagePortChannelImpl::CreatePorts(
|
| + params.message_ports, params.new_routing_ids,
|
| + base::MessageLoopProxy::current().get());
|
| +
|
| + WebSerializedScriptValue serialized_script_value;
|
| + if (params.is_data_raw_string) {
|
| + v8::HandleScope handle_scope(blink::mainThreadIsolate());
|
| + v8::Local<v8::Context> context = frame_->mainWorldScriptContext();
|
| + v8::Context::Scope context_scope(context);
|
| + V8ValueConverterImpl converter;
|
| + converter.SetDateAllowed(true);
|
| + converter.SetRegExpAllowed(true);
|
| + scoped_ptr<base::Value> value(new base::StringValue(params.data));
|
| + v8::Handle<v8::Value> result_value = converter.ToV8Value(value.get(),
|
| + context);
|
| + serialized_script_value = WebSerializedScriptValue::serialize(result_value);
|
| + } else {
|
| + serialized_script_value = WebSerializedScriptValue::fromString(params.data);
|
| + }
|
| +
|
| + // Create an event with the message. The next-to-last parameter to
|
| + // initMessageEvent is the last event ID, which is not used with postMessage.
|
| + WebDOMEvent event = frame_->document().createEvent("MessageEvent");
|
| + WebDOMMessageEvent msg_event = event.to<WebDOMMessageEvent>();
|
| + msg_event.initMessageEvent("message",
|
| + // |canBubble| and |cancellable| are always false
|
| + false, false,
|
| + serialized_script_value,
|
| + params.source_origin, source_frame, "", channels);
|
| +
|
| + // We must pass in the target_origin to do the security check on this side,
|
| + // since it may have changed since the original postMessage call was made.
|
| + WebSecurityOrigin target_origin;
|
| + if (!params.target_origin.empty()) {
|
| + target_origin =
|
| + WebSecurityOrigin::createFromString(WebString(params.target_origin));
|
| + }
|
| + frame_->dispatchMessageEventWithOriginCheck(target_origin, msg_event);
|
| +}
|
| +
|
| #if defined(OS_ANDROID)
|
| void RenderFrameImpl::OnSelectPopupMenuItems(
|
| bool canceled,
|
| @@ -3571,31 +3652,23 @@ bool RenderFrameImpl::willCheckAndDispatchMessageEvent(
|
| blink::WebDOMMessageEvent event) {
|
| DCHECK(!frame_ || frame_ == target_frame);
|
|
|
| + // Currently, a postMessage that targets a cross-process frame can be plumbed
|
| + // either through this function or RenderFrameProxy::postMessageEvent. This
|
| + // function is used when the target cross-process frame is a top-level frame
|
| + // which has been swapped out. In that case, the corresponding WebLocalFrame
|
| + // currently remains in the frame tree even in site-per-process mode (see
|
| + // OnSwapOut). RenderFrameProxy::postMessageEvent is used in
|
| + // --site-per-process mode for all other cases.
|
| + //
|
| + // TODO(alexmos, nasko): When swapped-out:// disappears, this should be
|
| + // cleaned up so that RenderFrameProxy::postMessageEvent is the only path for
|
| + // cross-process postMessages.
|
| if (!is_swapped_out_)
|
| return false;
|
|
|
| - ViewMsg_PostMessage_Params params;
|
| - params.is_data_raw_string = false;
|
| - params.data = event.data().toString();
|
| - params.source_origin = event.origin();
|
| - if (!target_origin.isNull())
|
| - params.target_origin = target_origin.toString();
|
| -
|
| - params.message_ports =
|
| - WebMessagePortChannelImpl::ExtractMessagePortIDs(event.releaseChannels());
|
| -
|
| - // Include the routing ID for the source frame (if one exists), which the
|
| - // browser process will translate into the routing ID for the equivalent
|
| - // frame in the target process.
|
| - params.source_routing_id = MSG_ROUTING_NONE;
|
| - if (source_frame) {
|
| - RenderViewImpl* source_view =
|
| - RenderViewImpl::FromWebView(source_frame->view());
|
| - if (source_view)
|
| - params.source_routing_id = source_view->routing_id();
|
| - }
|
| -
|
| - Send(new ViewHostMsg_RouteMessageEvent(render_view_->routing_id_, params));
|
| + CHECK(render_frame_proxy_);
|
| + render_frame_proxy_->postMessageEvent(
|
| + source_frame, render_frame_proxy_->web_frame(), target_origin, event);
|
| return true;
|
| }
|
|
|
|
|