Chromium Code Reviews| Index: extensions/renderer/guest_view/guest_view_internal_custom_bindings.cc |
| diff --git a/extensions/renderer/guest_view/guest_view_internal_custom_bindings.cc b/extensions/renderer/guest_view/guest_view_internal_custom_bindings.cc |
| index 902465fa9e1c9dd441e02411e92ad209fff365d9..a85573f3c96db853e5395c1bbd74bc2ac98fcd91 100644 |
| --- a/extensions/renderer/guest_view/guest_view_internal_custom_bindings.cc |
| +++ b/extensions/renderer/guest_view/guest_view_internal_custom_bindings.cc |
| @@ -7,15 +7,20 @@ |
| #include <string> |
| #include "base/bind.h" |
| +#include "base/command_line.h" |
| #include "components/guest_view/common/guest_view_constants.h" |
| #include "content/public/child/v8_value_converter.h" |
| +#include "content/public/common/content_switches.h" |
| +#include "content/public/renderer/render_frame.h" |
| #include "content/public/renderer/render_view.h" |
| #include "extensions/common/extension.h" |
| #include "extensions/common/extension_messages.h" |
| +#include "extensions/common/guest_view/extensions_guest_view_messages.h" |
| #include "extensions/renderer/guest_view/extensions_guest_view_container.h" |
| #include "extensions/renderer/guest_view/guest_view_request.h" |
| #include "extensions/renderer/script_context.h" |
| #include "third_party/WebKit/public/web/WebFrame.h" |
| +#include "third_party/WebKit/public/web/WebLocalFrame.h" |
| #include "third_party/WebKit/public/web/WebScopedUserGesture.h" |
| #include "third_party/WebKit/public/web/WebView.h" |
| #include "v8/include/v8.h" |
| @@ -24,6 +29,21 @@ using content::V8ValueConverter; |
| namespace extensions { |
| +namespace { |
| + |
| +content::RenderFrame* GetRenderFrame(v8::Handle<v8::Value> value) { |
| + v8::Local<v8::Context> context = |
| + v8::Local<v8::Object>::Cast(value)->CreationContext(); |
| + if (context.IsEmpty()) |
| + return nullptr; |
| + blink::WebLocalFrame* frame = blink::WebLocalFrame::frameForContext(context); |
| + if (!frame) |
| + return nullptr; |
| + return content::RenderFrame::FromWebFrame(frame); |
| +} |
| + |
| +} // namespace |
| + |
| GuestViewInternalCustomBindings::GuestViewInternalCustomBindings( |
| ScriptContext* context) |
| : ObjectBackedNativeHandler(context) { |
| @@ -49,6 +69,13 @@ GuestViewInternalCustomBindings::GuestViewInternalCustomBindings( |
| "RunWithGesture", |
| base::Bind(&GuestViewInternalCustomBindings::RunWithGesture, |
| base::Unretained(this))); |
| + RouteFunction("AttachIframeGuest", |
| + base::Bind(&GuestViewInternalCustomBindings::AttachIframeGuest, |
| + base::Unretained(this))); |
| + // TODO(lazyboy): There must be a better way to query command line from JS. |
| + RouteFunction("IsSitePerProcess", |
| + base::Bind(&GuestViewInternalCustomBindings::IsSitePerProcess, |
| + base::Unretained(this))); |
| } |
| void GuestViewInternalCustomBindings::AttachGuest( |
| @@ -209,4 +236,87 @@ void GuestViewInternalCustomBindings::RunWithGesture( |
| context()->CallFunction(v8::Local<v8::Function>::Cast(args[0]), 0, &no_args); |
| } |
| +void GuestViewInternalCustomBindings::AttachIframeGuest( |
| + const v8::FunctionCallbackInfo<v8::Value>& args) { |
| + // Allow for an optional callback parameter. |
| + const int num_required_params = 4; |
| + CHECK(args.Length() >= num_required_params && |
| + args.Length() <= (num_required_params + 1)); |
| + // Element Instance ID. |
| + CHECK(args[0]->IsInt32()); |
| + // Guest Instance ID. |
| + CHECK(args[1]->IsInt32()); |
| + // Attach Parameters. |
| + CHECK(args[2]->IsObject()); |
| + // <iframe>.contentWindow. |
| + CHECK(args[3]->IsObject()); |
| + // Optional Callback Function. |
| + CHECK(args.Length() <= num_required_params || |
| + args[num_required_params]->IsFunction()); |
| + LOG(WARNING) << "has_callback: " |
| + << (args.Length() >= (num_required_params + 1)); |
| + |
| + int element_instance_id = args[0]->Int32Value(); |
| + int guest_instance_id = args[1]->Int32Value(); |
| + LOG(WARNING) << "guest_instance_id: " << guest_instance_id |
| + << ", element_instance_id: " << element_instance_id; |
| + |
| + scoped_ptr<base::DictionaryValue> params; |
| + { |
| + scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create()); |
| + scoped_ptr<base::Value> params_as_value( |
| + converter->FromV8Value(args[2], context()->v8_context())); |
| + CHECK(params_as_value->IsType(base::Value::TYPE_DICTIONARY)); |
| + params.reset( |
| + static_cast<base::DictionaryValue*>(params_as_value.release())); |
| + } |
| + |
| + // Add flag to |params| to indicate that the element size is specified in |
| + // logical units. |
| + params->SetBoolean(guest_view::kElementSizeIsLogical, true); |
| + |
| + content::RenderFrame* render_frame = GetRenderFrame(args[3]); |
| + blink::WebLocalFrame* frame = render_frame->GetWebFrame(); |
| + |
| + // Parent must exist. |
| + blink::WebFrame* parent_frame = frame->parent(); |
| + DCHECK(parent_frame); |
| + DCHECK(parent_frame->isWebLocalFrame()); |
| + |
| + content::RenderFrame* embedder_parent_frame = |
| + content::RenderFrame::FromWebFrame(parent_frame); |
| + |
| + // Create a GuestViewContainer if it does not exist. |
| + // An element instance ID uniquely identifies a ExtensionsGuestViewContainer |
| + // within a RenderView. |
| + auto guest_view_container = static_cast<ExtensionsGuestViewContainer*>( |
| + GuestViewContainer::FromID(element_instance_id)); |
| + // This is the first time we hear about the |element_instance_id|. |
| + DCHECK(!guest_view_container); |
| + // TODO(lazyboy): Leaked, make this render_frame observer and destruct. |
| + guest_view_container = |
| + new extensions::ExtensionsGuestViewContainer(embedder_parent_frame); |
|
Fady Samuel
2015/05/26 16:42:15
Fix this.
|
| + guest_view_container->SetElementInstanceID(element_instance_id); |
| + |
| + linked_ptr<GuestViewRequest> request(new GuestViewAttachIframeRequest( |
| + guest_view_container, render_frame->GetRoutingID(), guest_instance_id, |
| + params.Pass(), args.Length() == (num_required_params + 1) |
| + ? args[num_required_params].As<v8::Function>() |
| + : v8::Local<v8::Function>(), |
| + args.GetIsolate())); |
| + guest_view_container->IssueRequest(request); |
| + |
| + args.GetReturnValue().Set(v8::Boolean::New(context()->isolate(), true)); |
| + |
| + LOG(WARNING) << "AttachLocalFrameToGuest complete"; |
| +} |
| + |
| +void GuestViewInternalCustomBindings::IsSitePerProcess( |
| + const v8::FunctionCallbackInfo<v8::Value>& args) { |
| + bool is_site_per_process = base::CommandLine::ForCurrentProcess()->HasSwitch( |
| + switches::kSitePerProcess); |
| + args.GetReturnValue().Set( |
| + v8::Boolean::New(context()->isolate(), is_site_per_process)); |
| +} |
| + |
| } // namespace extensions |