Index: extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container.cc |
diff --git a/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container.cc b/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container.cc |
index 420b3dfd3eb56c36827b91052130f94b90667c95..2bbfbaff0065694cd080d3380dd89cf3f68c8547 100644 |
--- a/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container.cc |
+++ b/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container.cc |
@@ -5,20 +5,82 @@ |
#include "extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container.h" |
#include "content/public/renderer/render_frame.h" |
+#include "content/public/renderer/render_view.h" |
#include "extensions/common/extension_messages.h" |
#include "extensions/common/guest_view/guest_view_constants.h" |
+#include "gin/arguments.h" |
+#include "gin/handle.h" |
+#include "gin/interceptor.h" |
+#include "gin/object_template_builder.h" |
+#include "gin/wrappable.h" |
#include "third_party/WebKit/public/web/WebDocument.h" |
#include "third_party/WebKit/public/web/WebLocalFrame.h" |
+#include "third_party/WebKit/public/web/WebView.h" |
namespace extensions { |
+namespace { |
+ |
+const char kPostMessageName[] = "postMessage"; |
+ |
+// The gin-backed scriptable object which is exposed by the BrowserPlugin for |
+// MimeHandlerViewContainer. This currently only implements "postMessage". |
+class ScriptableObject : public gin::Wrappable<ScriptableObject>, |
+ public gin::NamedPropertyInterceptor { |
+ public: |
+ static gin::WrapperInfo kWrapperInfo; |
+ |
+ static v8::Handle<v8::Object> Create( |
+ v8::Isolate* isolate, |
+ base::WeakPtr<MimeHandlerViewContainer> container) { |
+ ScriptableObject* scriptable_object = |
+ new ScriptableObject(isolate, container); |
+ return gin::CreateHandle(isolate, scriptable_object).ToV8()->ToObject(); |
+ } |
+ |
+ // gin::NamedPropertyInterceptor |
+ v8::Local<v8::Value> GetNamedProperty( |
+ v8::Isolate* isolate, |
+ const std::string& identifier) override { |
+ if (identifier == kPostMessageName) { |
+ return gin::CreateFunctionTemplate(isolate, |
+ base::Bind(&MimeHandlerViewContainer::PostMessage, |
+ container_, isolate))->GetFunction(); |
+ } |
+ return v8::Local<v8::Value>(); |
+ } |
+ |
+ private: |
+ ScriptableObject(v8::Isolate* isolate, |
+ base::WeakPtr<MimeHandlerViewContainer> container) |
+ : gin::NamedPropertyInterceptor(isolate, this), |
+ container_(container) {} |
+ virtual ~ScriptableObject() {} |
+ |
+ // gin::Wrappable |
+ virtual gin::ObjectTemplateBuilder GetObjectTemplateBuilder( |
+ v8::Isolate* isolate) override { |
+ return gin::Wrappable<ScriptableObject>::GetObjectTemplateBuilder(isolate) |
+ .AddNamedPropertyInterceptor(); |
Sam McNally
2014/12/18 05:36:47
2 more spaces?
raymes
2014/12/19 00:00:16
Done.
|
+ } |
+ |
+ base::WeakPtr<MimeHandlerViewContainer> container_; |
+}; |
+ |
+// static |
+gin::WrapperInfo ScriptableObject::kWrapperInfo = { gin::kEmbedderNativeGin }; |
+ |
+} // namespace |
+ |
MimeHandlerViewContainer::MimeHandlerViewContainer( |
content::RenderFrame* render_frame, |
const std::string& mime_type, |
const GURL& original_url) |
: GuestViewContainer(render_frame), |
mime_type_(mime_type), |
- original_url_(original_url) { |
+ original_url_(original_url), |
+ guest_proxy_routing_id_(-1), |
+ weak_factory_(this) { |
DCHECK(!mime_type_.empty()); |
is_embedded_ = !render_frame->GetWebFrame()->document().isPluginDocument(); |
} |
@@ -28,16 +90,6 @@ MimeHandlerViewContainer::~MimeHandlerViewContainer() { |
loader_->cancel(); |
} |
-void MimeHandlerViewContainer::DidFinishLoading() { |
- DCHECK(!is_embedded_); |
- CreateMimeHandlerViewGuest(); |
-} |
- |
-void MimeHandlerViewContainer::DidReceiveData(const char* data, |
- int data_length) { |
- html_string_ += std::string(data, data_length); |
-} |
- |
void MimeHandlerViewContainer::Ready() { |
blink::WebFrame* frame = render_frame()->GetWebFrame(); |
blink::WebURLLoaderOptions options; |
@@ -52,8 +104,29 @@ void MimeHandlerViewContainer::Ready() { |
loader_->loadAsynchronously(request, this); |
} |
+void MimeHandlerViewContainer::DidFinishLoading() { |
+ DCHECK(!is_embedded_); |
+ CreateMimeHandlerViewGuest(); |
+} |
+ |
+void MimeHandlerViewContainer::DidReceiveData(const char* data, |
+ int data_length) { |
+ html_string_ += std::string(data, data_length); |
+} |
+ |
+v8::Local<v8::Object> MimeHandlerViewContainer::v8ScriptableObject( |
+ v8::Isolate* isolate) { |
+ if (scriptable_object_.IsEmpty()) { |
+ v8::Local<v8::Object> object = |
+ ScriptableObject::Create(isolate, weak_factory_.GetWeakPtr()); |
+ scriptable_object_.reset(object); |
+ } |
+ return scriptable_object_.NewHandle(isolate); |
+} |
+ |
bool MimeHandlerViewContainer::HandlesMessage(const IPC::Message& message) { |
- return message.type() == ExtensionMsg_CreateMimeHandlerViewGuestACK::ID; |
+ return message.type() == ExtensionMsg_CreateMimeHandlerViewGuestACK::ID || |
+ message.type() == ExtensionMsg_GuestAttached::ID; |
} |
bool MimeHandlerViewContainer::OnMessage(const IPC::Message& message) { |
@@ -61,6 +134,7 @@ bool MimeHandlerViewContainer::OnMessage(const IPC::Message& message) { |
IPC_BEGIN_MESSAGE_MAP(MimeHandlerViewContainer, message) |
IPC_MESSAGE_HANDLER(ExtensionMsg_CreateMimeHandlerViewGuestACK, |
OnCreateMimeHandlerViewGuestACK) |
+ IPC_MESSAGE_HANDLER(ExtensionMsg_GuestAttached, OnGuestAttached) |
IPC_MESSAGE_UNHANDLED(handled = false) |
IPC_END_MESSAGE_MAP() |
return handled; |
@@ -81,6 +155,38 @@ void MimeHandlerViewContainer::didFinishLoading( |
CreateMimeHandlerViewGuest(); |
} |
+void MimeHandlerViewContainer::PostMessage(v8::Isolate* isolate, |
+ v8::Handle<v8::Value> message) { |
+ content::RenderView* guest_proxy_render_view = |
+ content::RenderView::FromRoutingID(guest_proxy_routing_id_); |
+ if (!guest_proxy_render_view) |
+ return; |
+ blink::WebFrame* guest_proxy_frame = |
+ guest_proxy_render_view->GetWebView()->mainFrame(); |
+ if (!guest_proxy_frame) |
+ return; |
+ |
+ v8::Local<v8::Object> guest_proxy_window = |
Sam McNally
2014/12/18 05:36:47
I think this would be nicer if it used a gin::Dict
raymes
2014/12/19 00:00:16
Done.
|
+ guest_proxy_frame->mainWorldScriptContext()->Global(); |
+ std::string post_message_name(kPostMessageName); |
+ v8::Handle<v8::String> post_message_string = v8::String::NewFromUtf8( |
+ isolate, post_message_name.c_str(), v8::String::kNormalString, |
+ post_message_name.size()); |
+ v8::Handle<v8::Value> post_message = |
+ guest_proxy_window->Get(post_message_string); |
+ if (post_message.IsEmpty() || !post_message->IsFunction()) |
+ return; |
+ |
+ v8::Handle<v8::Value> args[] = { |
+ message, |
+ // Post the message to any domain inside the browser plugin. The embedder |
+ // should already know what is embedded. |
+ v8::String::NewFromUtf8(isolate, "*", v8::String::kNormalString, 1) |
Sam McNally
2014/12/18 05:36:47
gin::StringToV8?
raymes
2014/12/19 00:00:16
Done.
|
+ }; |
+ post_message.As<v8::Function>()->Call( |
+ guest_proxy_window, arraysize(args), args); |
+} |
+ |
void MimeHandlerViewContainer::OnCreateMimeHandlerViewGuestACK( |
int element_instance_id) { |
DCHECK_NE(this->element_instance_id(), guestview::kInstanceIDNone); |
@@ -88,6 +194,11 @@ void MimeHandlerViewContainer::OnCreateMimeHandlerViewGuestACK( |
render_frame()->AttachGuest(element_instance_id); |
} |
+void MimeHandlerViewContainer::OnGuestAttached(int /* unused */, |
+ int guest_proxy_routing_id) { |
+ guest_proxy_routing_id_ = guest_proxy_routing_id; |
+} |
+ |
void MimeHandlerViewContainer::CreateMimeHandlerViewGuest() { |
// The loader has completed loading |html_string_| so we can dispose it. |
loader_.reset(); |