Chromium Code Reviews| 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(); |