Commit 0437317b authored by Kevin McNee's avatar Kevin McNee Committed by Commit Bot

Remove browser plugin support in guest view JS implementation

Now that the flags for browser plugin have been removed, we remove the
code to support browser plugin from the guest view JS implementation.

Bug: 533069
Change-Id: Ida04f0ce856d0f318835d6369558a3e38cac47e9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1943579Reviewed-by: default avatarJames MacLean <wjmaclean@chromium.org>
Reviewed-by: default avatarIstiaque Ahmed <lazyboy@chromium.org>
Commit-Queue: Kevin McNee <mcnee@chromium.org>
Cr-Commit-Position: refs/heads/master@{#720593}
parent 973d6c53
...@@ -755,10 +755,6 @@ std::vector<Dispatcher::JsResourceInfo> Dispatcher::GetJsResources() { ...@@ -755,10 +755,6 @@ std::vector<Dispatcher::JsResourceInfo> Dispatcher::GetJsResources() {
// Platform app sources that are not API-specific.. // Platform app sources that are not API-specific..
{"platformApp", IDR_PLATFORM_APP_JS}, {"platformApp", IDR_PLATFORM_APP_JS},
// GuestView.
{"guestViewIframe", IDR_GUEST_VIEW_IFRAME_JS},
{"guestViewIframeContainer", IDR_GUEST_VIEW_IFRAME_CONTAINER_JS},
}; };
return resources; return resources;
...@@ -1306,12 +1302,8 @@ void Dispatcher::UpdateOriginPermissions(const Extension& extension) { ...@@ -1306,12 +1302,8 @@ void Dispatcher::UpdateOriginPermissions(const Extension& extension) {
void Dispatcher::EnableCustomElementWhiteList() { void Dispatcher::EnableCustomElementWhiteList() {
blink::WebCustomElement::AddEmbedderCustomElementName("appview"); blink::WebCustomElement::AddEmbedderCustomElementName("appview");
blink::WebCustomElement::AddEmbedderCustomElementName("appviewbrowserplugin");
blink::WebCustomElement::AddEmbedderCustomElementName("extensionoptions"); blink::WebCustomElement::AddEmbedderCustomElementName("extensionoptions");
blink::WebCustomElement::AddEmbedderCustomElementName(
"extensionoptionsbrowserplugin");
blink::WebCustomElement::AddEmbedderCustomElementName("webview"); blink::WebCustomElement::AddEmbedderCustomElementName("webview");
blink::WebCustomElement::AddEmbedderCustomElementName("webviewbrowserplugin");
} }
void Dispatcher::UpdateAllBindings() { void Dispatcher::UpdateAllBindings() {
...@@ -1430,11 +1422,6 @@ void Dispatcher::RequireGuestViewModules(ScriptContext* context) { ...@@ -1430,11 +1422,6 @@ void Dispatcher::RequireGuestViewModules(ScriptContext* context) {
module_system->Require("webViewDeny"); module_system->Require("webViewDeny");
} }
if (requires_guest_view_module) {
module_system->Require("guestViewIframe");
module_system->Require("guestViewIframeContainer");
}
if (requires_guest_view_module) { if (requires_guest_view_module) {
// If a frame has guest view custom elements defined, we need to make sure // If a frame has guest view custom elements defined, we need to make sure
// the custom elements are also defined in subframes. The subframes will // the custom elements are also defined in subframes. The subframes will
......
...@@ -82,14 +82,6 @@ GuestViewInternalCustomBindings::GuestViewInternalCustomBindings( ...@@ -82,14 +82,6 @@ GuestViewInternalCustomBindings::GuestViewInternalCustomBindings(
GuestViewInternalCustomBindings::~GuestViewInternalCustomBindings() {} GuestViewInternalCustomBindings::~GuestViewInternalCustomBindings() {}
void GuestViewInternalCustomBindings::AddRoutes() { void GuestViewInternalCustomBindings::AddRoutes() {
RouteHandlerFunction(
"AttachGuest",
base::BindRepeating(&GuestViewInternalCustomBindings::AttachGuest,
base::Unretained(this)));
RouteHandlerFunction(
"DetachGuest",
base::BindRepeating(&GuestViewInternalCustomBindings::DetachGuest,
base::Unretained(this)));
RouteHandlerFunction( RouteHandlerFunction(
"AttachIframeGuest", "AttachIframeGuest",
base::BindRepeating(&GuestViewInternalCustomBindings::AttachIframeGuest, base::BindRepeating(&GuestViewInternalCustomBindings::AttachIframeGuest,
...@@ -98,10 +90,6 @@ void GuestViewInternalCustomBindings::AddRoutes() { ...@@ -98,10 +90,6 @@ void GuestViewInternalCustomBindings::AddRoutes() {
"DestroyContainer", "DestroyContainer",
base::BindRepeating(&GuestViewInternalCustomBindings::DestroyContainer, base::BindRepeating(&GuestViewInternalCustomBindings::DestroyContainer,
base::Unretained(this))); base::Unretained(this)));
RouteHandlerFunction(
"GetContentWindow",
base::BindRepeating(&GuestViewInternalCustomBindings::GetContentWindow,
base::Unretained(this)));
RouteHandlerFunction( RouteHandlerFunction(
"GetViewFromID", "GetViewFromID",
base::BindRepeating(&GuestViewInternalCustomBindings::GetViewFromID, base::BindRepeating(&GuestViewInternalCustomBindings::GetViewFromID,
...@@ -153,89 +141,6 @@ void GuestViewInternalCustomBindings::ResetMapEntry( ...@@ -153,89 +141,6 @@ void GuestViewInternalCustomBindings::ResetMapEntry(
new GuestViewHostMsg_ViewGarbageCollected(view_instance_id)); new GuestViewHostMsg_ViewGarbageCollected(view_instance_id));
} }
void GuestViewInternalCustomBindings::AttachGuest(
const v8::FunctionCallbackInfo<v8::Value>& args) {
// Allow for an optional callback parameter.
CHECK(args.Length() >= 3 && args.Length() <= 4);
// Element Instance ID.
CHECK(args[0]->IsInt32());
// Guest Instance ID.
CHECK(args[1]->IsInt32());
// Attach Parameters.
CHECK(args[2]->IsObject());
// Optional Callback Function.
CHECK(args.Length() < 4 || args[3]->IsFunction());
int element_instance_id = args[0].As<v8::Int32>()->Value();
// An element instance ID uniquely identifies a GuestViewContainer.
auto* guest_view_container =
guest_view::GuestViewContainer::FromID(element_instance_id);
// TODO(fsamuel): Should we be reporting an error if the element instance ID
// is invalid?
if (!guest_view_container)
return;
// Retain a weak pointer so we can easily test if the container goes away.
auto weak_ptr = guest_view_container->GetWeakPtr();
int guest_instance_id = args[1].As<v8::Int32>()->Value();
std::unique_ptr<base::DictionaryValue> params = base::DictionaryValue::From(
content::V8ValueConverter::Create()->FromV8Value(
args[2], context()->v8_context()));
CHECK(params);
// We should be careful that some malicious JS in the GuestView's embedder
// hasn't destroyed |guest_view_container| during the enumeration of the
// properties of the guest's object during extraction of |params| above
// (see https://crbug.com/683523).
if (!weak_ptr)
return;
// Add flag to |params| to indicate that the element size is specified in
// logical units.
params->SetBoolean(guest_view::kElementSizeIsLogical, true);
std::unique_ptr<guest_view::GuestViewRequest> request(
new guest_view::GuestViewAttachRequest(
guest_view_container, guest_instance_id, std::move(params),
args.Length() == 4 ? args[3].As<v8::Function>()
: v8::Local<v8::Function>(),
args.GetIsolate()));
guest_view_container->IssueRequest(std::move(request));
args.GetReturnValue().Set(v8::Boolean::New(context()->isolate(), true));
}
void GuestViewInternalCustomBindings::DetachGuest(
const v8::FunctionCallbackInfo<v8::Value>& args) {
// Allow for an optional callback parameter.
CHECK(args.Length() >= 1 && args.Length() <= 2);
// Element Instance ID.
CHECK(args[0]->IsInt32());
// Optional Callback Function.
CHECK(args.Length() < 2 || args[1]->IsFunction());
int element_instance_id = args[0].As<v8::Int32>()->Value();
// An element instance ID uniquely identifies a GuestViewContainer.
auto* guest_view_container =
guest_view::GuestViewContainer::FromID(element_instance_id);
// TODO(fsamuel): Should we be reporting an error if the element instance ID
// is invalid?
if (!guest_view_container)
return;
std::unique_ptr<guest_view::GuestViewRequest> request(
new guest_view::GuestViewDetachRequest(
guest_view_container, args.Length() == 2 ? args[1].As<v8::Function>()
: v8::Local<v8::Function>(),
args.GetIsolate()));
guest_view_container->IssueRequest(std::move(request));
args.GetReturnValue().Set(v8::Boolean::New(context()->isolate(), true));
}
void GuestViewInternalCustomBindings::AttachIframeGuest( void GuestViewInternalCustomBindings::AttachIframeGuest(
const v8::FunctionCallbackInfo<v8::Value>& args) { const v8::FunctionCallbackInfo<v8::Value>& args) {
// Allow for an optional callback parameter. // Allow for an optional callback parameter.
...@@ -332,31 +237,6 @@ void GuestViewInternalCustomBindings::DestroyContainer( ...@@ -332,31 +237,6 @@ void GuestViewInternalCustomBindings::DestroyContainer(
guest_view_container->Destroy(false /* embedder_frame_destroyed */); guest_view_container->Destroy(false /* embedder_frame_destroyed */);
} }
void GuestViewInternalCustomBindings::GetContentWindow(
const v8::FunctionCallbackInfo<v8::Value>& args) {
// Default to returning null.
args.GetReturnValue().SetNull();
if (args.Length() != 1)
return;
// The routing ID for the RenderView.
if (!args[0]->IsInt32())
return;
int view_id = args[0].As<v8::Int32>()->Value();
if (view_id == MSG_ROUTING_NONE)
return;
content::RenderView* view = content::RenderView::FromRoutingID(view_id);
if (!view)
return;
blink::WebFrame* frame = view->GetWebView()->MainFrame();
v8::Local<v8::Value> window = frame->GlobalProxy();
args.GetReturnValue().Set(window);
}
void GuestViewInternalCustomBindings::GetViewFromID( void GuestViewInternalCustomBindings::GetViewFromID(
const v8::FunctionCallbackInfo<v8::Value>& args) { const v8::FunctionCallbackInfo<v8::Value>& args) {
// Default to returning null. // Default to returning null.
......
...@@ -25,10 +25,10 @@ class GuestViewInternalCustomBindings : public ObjectBackedNativeHandler { ...@@ -25,10 +25,10 @@ class GuestViewInternalCustomBindings : public ObjectBackedNativeHandler {
// weak view reference held in |view_map_|. // weak view reference held in |view_map_|.
static void ResetMapEntry(const v8::WeakCallbackInfo<int>& data); static void ResetMapEntry(const v8::WeakCallbackInfo<int>& data);
// AttachGuest attaches a GuestView to a provided container element. Once // AttachIframeGuest attaches a GuestView to a provided <iframe> container
// attached, the GuestView will participate in layout of the container page // element. Once attached, the GuestView will participate in layout of the
// and become visible on screen. // container page and become visible on screen.
// AttachGuest takes four parameters: // AttachIframeGuest takes five parameters:
// |element_instance_id| uniquely identifies a container within the content // |element_instance_id| uniquely identifies a container within the content
// module is able to host GuestViews. // module is able to host GuestViews.
// |guest_instance_id| uniquely identifies an unattached GuestView. // |guest_instance_id| uniquely identifies an unattached GuestView.
...@@ -36,30 +36,13 @@ class GuestViewInternalCustomBindings : public ObjectBackedNativeHandler { ...@@ -36,30 +36,13 @@ class GuestViewInternalCustomBindings : public ObjectBackedNativeHandler {
// container element at the time of attachment. These parameters are passed // container element at the time of attachment. These parameters are passed
// down to the GuestView. The GuestView may use these parameters to update the // down to the GuestView. The GuestView may use these parameters to update the
// state of the guest hosted in another process. // state of the guest hosted in another process.
// |contentWindow| is used to identify the RenderFrame of the <iframe>
// container element.
// |callback| is an optional callback that is called once attachment is // |callback| is an optional callback that is called once attachment is
// complete. The callback takes in a parameter for the WindowProxy of the // complete. The callback takes in a parameter for the WindowProxy of the
// guest identified by |guest_instance_id|. // guest identified by |guest_instance_id|.
void AttachGuest(const v8::FunctionCallbackInfo<v8::Value>& args);
// DetachGuest detaches the container container specified from the associated
// GuestViewBase. DetachGuest takes two parameters:
// |element_instance_id| uniquely identifies a container within the content
// module is able to host GuestViews.
// |callback| is an optional callback that is called once the container has
// been detached.
void DetachGuest(const v8::FunctionCallbackInfo<v8::Value>& args);
// AttachIframeGuest is --site-per-process variant of AttachGuest().
//
// AttachIframeGuest takes a |contentWindow| parameter in addition to the
// parameters to AttachGuest. That parameter is used to identify the
// RenderFrame of the <iframe> container element.
void AttachIframeGuest(const v8::FunctionCallbackInfo<v8::Value>& args); void AttachIframeGuest(const v8::FunctionCallbackInfo<v8::Value>& args);
// GetContentWindow takes in a RenderView routing ID and returns the
// Window JavaScript object for that RenderView.
void GetContentWindow(const v8::FunctionCallbackInfo<v8::Value>& args);
// Destroys the GuestViewContainer given an element instance ID in |args|. // Destroys the GuestViewContainer given an element instance ID in |args|.
void DestroyContainer(const v8::FunctionCallbackInfo<v8::Value>& args); void DestroyContainer(const v8::FunctionCallbackInfo<v8::Value>& args);
......
...@@ -26,8 +26,6 @@ ...@@ -26,8 +26,6 @@
<include name="IDR_GUEST_VIEW_CONTAINER_ELEMENT_JS" file="guest_view/guest_view_container_element.js" type="BINDATA" /> <include name="IDR_GUEST_VIEW_CONTAINER_ELEMENT_JS" file="guest_view/guest_view_container_element.js" type="BINDATA" />
<include name="IDR_GUEST_VIEW_DENY_JS" file="guest_view/guest_view_deny.js" type="BINDATA" /> <include name="IDR_GUEST_VIEW_DENY_JS" file="guest_view/guest_view_deny.js" type="BINDATA" />
<include name="IDR_GUEST_VIEW_EVENTS_JS" file="guest_view/guest_view_events.js" type="BINDATA" /> <include name="IDR_GUEST_VIEW_EVENTS_JS" file="guest_view/guest_view_events.js" type="BINDATA" />
<include name="IDR_GUEST_VIEW_IFRAME_CONTAINER_JS" file="guest_view/guest_view_iframe_container.js" type="BINDATA" />
<include name="IDR_GUEST_VIEW_IFRAME_JS" file="guest_view/guest_view_iframe.js" type="BINDATA" />
<include name="IDR_GUEST_VIEW_JS" file="guest_view/guest_view.js" type="BINDATA" /> <include name="IDR_GUEST_VIEW_JS" file="guest_view/guest_view.js" type="BINDATA" />
<include name="IDR_IMAGE_UTIL_JS" file="image_util.js" type="BINDATA" /> <include name="IDR_IMAGE_UTIL_JS" file="image_util.js" type="BINDATA" />
<include name="IDR_KEEP_ALIVE_JS" file="keep_alive.js" type="BINDATA" /> <include name="IDR_KEEP_ALIVE_JS" file="keep_alive.js" type="BINDATA" />
......
...@@ -49,7 +49,7 @@ AppViewImpl.prototype.connect = function(app, data, callback) { ...@@ -49,7 +49,7 @@ AppViewImpl.prototype.connect = function(app, data, callback) {
this.app = app; this.app = app;
this.data = data; this.data = data;
this.guest.destroy($Function.bind(this.prepareForReattach$, this)); this.guest.destroy($Function.bind(this.prepareForReattach, this));
this.guest.create(this.buildParams(), $Function.bind(function() { this.guest.create(this.buildParams(), $Function.bind(function() {
if (!this.guest.getId()) { if (!this.guest.getId()) {
var errorMsg = 'Unable to connect to app "' + app + '".'; var errorMsg = 'Unable to connect to app "' + app + '".';
...@@ -60,7 +60,7 @@ AppViewImpl.prototype.connect = function(app, data, callback) { ...@@ -60,7 +60,7 @@ AppViewImpl.prototype.connect = function(app, data, callback) {
} }
return; return;
} }
this.attachWindow$(); this.attachWindow();
if (callback) { if (callback) {
callback(true); callback(true);
} }
......
...@@ -39,7 +39,7 @@ ExtensionOptionsImpl.prototype.buildContainerParams = function() { ...@@ -39,7 +39,7 @@ ExtensionOptionsImpl.prototype.buildContainerParams = function() {
ExtensionOptionsImpl.prototype.createGuest = function() { ExtensionOptionsImpl.prototype.createGuest = function() {
// Destroy the old guest if one exists. // Destroy the old guest if one exists.
this.guest.destroy($Function.bind(this.prepareForReattach$, this)); this.guest.destroy($Function.bind(this.prepareForReattach, this));
this.guest.create(this.buildParams(), $Function.bind(function() { this.guest.create(this.buildParams(), $Function.bind(function() {
if (!this.guest.getId()) { if (!this.guest.getId()) {
...@@ -48,7 +48,7 @@ ExtensionOptionsImpl.prototype.createGuest = function() { ...@@ -48,7 +48,7 @@ ExtensionOptionsImpl.prototype.createGuest = function() {
var createFailedEvent = new Event('createfailed', { bubbles: true }); var createFailedEvent = new Event('createfailed', { bubbles: true });
this.dispatchEvent(createFailedEvent); this.dispatchEvent(createFailedEvent);
} else { } else {
this.attachWindow$(); this.attachWindow();
} }
}, this)); }, this));
}; };
......
...@@ -5,10 +5,7 @@ ...@@ -5,10 +5,7 @@
// This module implements a wrapper for a guestview that manages its // This module implements a wrapper for a guestview that manages its
// creation, attaching, and destruction. // creation, attaching, and destruction.
// Methods ending with $ will be overwritten by guest_view_iframe.js var $HTMLIFrameElement = require('safeMethods').SafeMethods.$HTMLIFrameElement;
// TODO(mcnee): When BrowserPlugin is removed, merge
// guest_view_iframe.js into this file.
var CreateEvent = require('guestViewEvents').CreateEvent; var CreateEvent = require('guestViewEvents').CreateEvent;
var GuestViewInternal = getInternalApi('guestViewInternal'); var GuestViewInternal = getInternalApi('guestViewInternal');
var GuestViewInternalNatives = requireNative('guest_view_internal'); var GuestViewInternalNatives = requireNative('guest_view_internal');
...@@ -26,6 +23,18 @@ var ERROR_MSG_NOT_CREATED = 'The guest has not been created.'; ...@@ -26,6 +23,18 @@ var ERROR_MSG_NOT_CREATED = 'The guest has not been created.';
// Properties. // Properties.
var PROPERTY_ON_RESIZE = 'onresize'; var PROPERTY_ON_RESIZE = 'onresize';
var getIframeContentWindow = function(viewInstanceId) {
var view = GuestViewInternalNatives.GetViewFromID(viewInstanceId);
if (!view)
return null;
var internalIframeElement = view.internalElement;
if (internalIframeElement)
return $HTMLIFrameElement.contentWindow.get(internalIframeElement);
return null;
};
// Contains and hides the internal implementation details of |GuestView|, // Contains and hides the internal implementation details of |GuestView|,
// including maintaining its state and enforcing the proper usage of its API // including maintaining its state and enforcing the proper usage of its API
// fucntions. // fucntions.
...@@ -154,18 +163,26 @@ GuestViewImpl.prototype.weakWrapper = function(func, viewInstanceId) { ...@@ -154,18 +163,26 @@ GuestViewImpl.prototype.weakWrapper = function(func, viewInstanceId) {
}; };
// Internal implementation of attach(). // Internal implementation of attach().
GuestViewImpl.prototype.attachImpl$ = function( GuestViewImpl.prototype.attachImpl = function(
internalInstanceId, viewInstanceId, attachParams, callback) { internalInstanceId, viewInstanceId, attachParams, callback) {
var view = GuestViewInternalNatives.GetViewFromID(viewInstanceId);
if (!view.elementAttached) {
// Defer the attachment until the <webview> element is attached.
view.deferredAttachCallback = $Function.bind(this.attachImpl,
this, internalInstanceId, viewInstanceId, attachParams, callback);
return;
};
// Check the current state. // Check the current state.
if (!this.checkState('attach')) { if (!this.checkState('attach')) {
this.handleCallback(callback); this.handleCallback(callback);
return; return;
} }
// Callback wrapper function to store the contentWindow from the attachGuest() // Callback wrapper function to set the contentWindow following attachment,
// callback, handle potential attaching failure, register an automatic detach,
// and advance the queue. // and advance the queue.
var callbackWrapper = function(callback, contentWindow) { var callbackWrapper = function(callback) {
var contentWindow = getIframeContentWindow(viewInstanceId);
// Check if attaching failed. // Check if attaching failed.
if (!contentWindow) { if (!contentWindow) {
this.state = GuestViewImpl.GuestState.GUEST_STATE_CREATED; this.state = GuestViewImpl.GuestState.GUEST_STATE_CREATED;
...@@ -179,10 +196,10 @@ GuestViewImpl.prototype.attachImpl$ = function( ...@@ -179,10 +196,10 @@ GuestViewImpl.prototype.attachImpl$ = function(
}; };
attachParams['instanceId'] = viewInstanceId; attachParams['instanceId'] = viewInstanceId;
GuestViewInternalNatives.AttachGuest( var contentWindow = getIframeContentWindow(viewInstanceId);
internalInstanceId, // |contentWindow| is used to retrieve the RenderFrame in cpp.
this.id, GuestViewInternalNatives.AttachIframeGuest(
attachParams, internalInstanceId, this.id, attachParams, contentWindow,
$Function.bind(callbackWrapper, this, callback)); $Function.bind(callbackWrapper, this, callback));
this.internalInstanceId = internalInstanceId; this.internalInstanceId = internalInstanceId;
...@@ -202,7 +219,7 @@ GuestViewImpl.prototype.attachImpl$ = function( ...@@ -202,7 +219,7 @@ GuestViewImpl.prototype.attachImpl$ = function(
}; };
// Internal implementation of create(). // Internal implementation of create().
GuestViewImpl.prototype.createImpl$ = function(createParams, callback) { GuestViewImpl.prototype.createImpl = function(createParams, callback) {
// Check the current state. // Check the current state.
if (!this.checkState('create')) { if (!this.checkState('create')) {
this.handleCallback(callback); this.handleCallback(callback);
...@@ -214,8 +231,6 @@ GuestViewImpl.prototype.createImpl$ = function(createParams, callback) { ...@@ -214,8 +231,6 @@ GuestViewImpl.prototype.createImpl$ = function(createParams, callback) {
// queue. // queue.
var callbackWrapper = function(callback, guestInfo) { var callbackWrapper = function(callback, guestInfo) {
this.id = guestInfo.id; this.id = guestInfo.id;
this.contentWindow =
GuestViewInternalNatives.GetContentWindow(guestInfo.contentWindowId);
// Check if creation failed. // Check if creation failed.
if (this.id === 0) { if (this.id === 0) {
...@@ -227,8 +242,8 @@ GuestViewImpl.prototype.createImpl$ = function(createParams, callback) { ...@@ -227,8 +242,8 @@ GuestViewImpl.prototype.createImpl$ = function(createParams, callback) {
this.handleCallback(callback); this.handleCallback(callback);
}; };
this.sendCreateRequest(createParams, this.sendCreateRequest(
$Function.bind(callbackWrapper, this, callback)); createParams, $Function.bind(callbackWrapper, this, callback));
this.state = GuestViewImpl.GuestState.GUEST_STATE_CREATED; this.state = GuestViewImpl.GuestState.GUEST_STATE_CREATED;
}; };
...@@ -239,7 +254,7 @@ GuestViewImpl.prototype.sendCreateRequest = function( ...@@ -239,7 +254,7 @@ GuestViewImpl.prototype.sendCreateRequest = function(
}; };
// Internal implementation of destroy(). // Internal implementation of destroy().
GuestViewImpl.prototype.destroyImpl$ = function(callback) { GuestViewImpl.prototype.destroyImpl = function(callback) {
// Check the current state. // Check the current state.
if (!this.checkState('destroy')) { if (!this.checkState('destroy')) {
this.handleCallback(callback); this.handleCallback(callback);
...@@ -252,18 +267,7 @@ GuestViewImpl.prototype.destroyImpl$ = function(callback) { ...@@ -252,18 +267,7 @@ GuestViewImpl.prototype.destroyImpl$ = function(callback) {
return; return;
} }
// If this guest is attached, then detach it first. // Reset the state of the destroyed guest;
if (!!this.internalInstanceId) {
GuestViewInternalNatives.DetachGuest(this.internalInstanceId);
}
GuestViewInternal.destroyGuest(
this.id, $Function.bind(this.handleCallback, this, callback));
// Reset the state of the destroyed guest; it's ok to do this after shipping
// the callback to the GuestViewInternal api, since it runs asynchronously,
// and the changes below will happen before the next item from the action
// queue is executed.
this.contentWindow = null; this.contentWindow = null;
this.id = 0; this.id = 0;
this.internalInstanceId = 0; this.internalInstanceId = 0;
...@@ -271,22 +275,10 @@ GuestViewImpl.prototype.destroyImpl$ = function(callback) { ...@@ -271,22 +275,10 @@ GuestViewImpl.prototype.destroyImpl$ = function(callback) {
if (ResizeEvent.hasListener(this.callOnResize)) { if (ResizeEvent.hasListener(this.callOnResize)) {
ResizeEvent.removeListener(this.callOnResize); ResizeEvent.removeListener(this.callOnResize);
} }
};
// Internal implementation of detach().
GuestViewImpl.prototype.detachImpl = function(callback) {
// Check the current state.
if (!this.checkState('detach')) {
this.handleCallback(callback);
return;
}
GuestViewInternalNatives.DetachGuest( // Handle callback at end to avoid handling items in the action queue out of
this.internalInstanceId, // order, since the callback is run synchronously here.
$Function.bind(this.handleCallback, this, callback)); this.handleCallback(callback);
this.internalInstanceId = 0;
this.state = GuestViewImpl.GuestState.GUEST_STATE_CREATED;
}; };
// Internal implementation of setSize(). // Internal implementation of setSize().
...@@ -315,7 +307,7 @@ GuestView.prototype.__proto__ = null; ...@@ -315,7 +307,7 @@ GuestView.prototype.__proto__ = null;
GuestView.prototype.attach = function( GuestView.prototype.attach = function(
internalInstanceId, viewInstanceId, attachParams, callback) { internalInstanceId, viewInstanceId, attachParams, callback) {
var internal = this.internal; var internal = this.internal;
$Array.push(internal.actionQueue, $Function.bind(internal.attachImpl$, $Array.push(internal.actionQueue, $Function.bind(internal.attachImpl,
internal, internalInstanceId, viewInstanceId, attachParams, callback)); internal, internalInstanceId, viewInstanceId, attachParams, callback));
internal.performNextAction(); internal.performNextAction();
}; };
...@@ -323,7 +315,7 @@ GuestView.prototype.attach = function( ...@@ -323,7 +315,7 @@ GuestView.prototype.attach = function(
// Creates the guestview. // Creates the guestview.
GuestView.prototype.create = function(createParams, callback) { GuestView.prototype.create = function(createParams, callback) {
var internal = this.internal; var internal = this.internal;
$Array.push(internal.actionQueue, $Function.bind(internal.createImpl$, $Array.push(internal.actionQueue, $Function.bind(internal.createImpl,
internal, createParams, callback)); internal, createParams, callback));
internal.performNextAction(); internal.performNextAction();
}; };
...@@ -334,16 +326,7 @@ GuestView.prototype.destroy = function(callback) { ...@@ -334,16 +326,7 @@ GuestView.prototype.destroy = function(callback) {
var internal = this.internal; var internal = this.internal;
$Array.push( $Array.push(
internal.actionQueue, internal.actionQueue,
$Function.bind(internal.destroyImpl$, internal, callback)); $Function.bind(internal.destroyImpl, internal, callback));
internal.performNextAction();
};
// Detaches the guestview from its container.
// Note: This is not currently used.
GuestView.prototype.detach = function(callback) {
var internal = this.internal;
$Array.push(internal.actionQueue,
$Function.bind(internal.detachImpl, internal, callback));
internal.performNextAction(); internal.performNextAction();
}; };
...@@ -369,6 +352,4 @@ GuestView.prototype.getId = function() { ...@@ -369,6 +352,4 @@ GuestView.prototype.getId = function() {
// Exports // Exports
exports.$set('GuestView', GuestView); exports.$set('GuestView', GuestView);
// TODO(mcnee): Don't export GuestViewImpl once guest_view_iframe.js is gone.
exports.$set('GuestViewImpl', GuestViewImpl);
exports.$set('ResizeEvent', ResizeEvent); exports.$set('ResizeEvent', ResizeEvent);
...@@ -5,12 +5,9 @@ ...@@ -5,12 +5,9 @@
// This module implements the shared functionality for different guestview // This module implements the shared functionality for different guestview
// containers, such as web_view, app_view, etc. // containers, such as web_view, app_view, etc.
// Methods ending with $ will be overwritten by guest_view_iframe_container.js.
// TODO(mcnee): When BrowserPlugin is removed, merge
// guest_view_iframe_container.js into this file.
var $parseInt = require('safeMethods').SafeMethods.$parseInt; var $parseInt = require('safeMethods').SafeMethods.$parseInt;
var $getComputedStyle = require('safeMethods').SafeMethods.$getComputedStyle; var $getComputedStyle = require('safeMethods').SafeMethods.$getComputedStyle;
var $Document = require('safeMethods').SafeMethods.$Document;
var $Element = require('safeMethods').SafeMethods.$Element; var $Element = require('safeMethods').SafeMethods.$Element;
var $EventTarget = require('safeMethods').SafeMethods.$EventTarget; var $EventTarget = require('safeMethods').SafeMethods.$EventTarget;
var $HTMLElement = require('safeMethods').SafeMethods.$HTMLElement; var $HTMLElement = require('safeMethods').SafeMethods.$HTMLElement;
...@@ -31,7 +28,7 @@ function GuestViewContainer(element, viewType) { ...@@ -31,7 +28,7 @@ function GuestViewContainer(element, viewType) {
this.guest = new GuestView(viewType); this.guest = new GuestView(viewType);
this.setupAttributes(); this.setupAttributes();
this.internalElement = this.createInternalElement$(); this.internalElement = this.createInternalElement();
this.shadowRoot = $Element.attachShadow(this.element, {mode: 'closed'}); this.shadowRoot = $Element.attachShadow(this.element, {mode: 'closed'});
$Node.appendChild(this.shadowRoot, this.internalElement); $Node.appendChild(this.shadowRoot, this.internalElement);
...@@ -70,30 +67,36 @@ GuestViewContainer.prototype.setupGuestProperty = function() { ...@@ -70,30 +67,36 @@ GuestViewContainer.prototype.setupGuestProperty = function() {
}); });
}; };
GuestViewContainer.prototype.createInternalElement$ = function() { GuestViewContainer.prototype.createInternalElement = function() {
// We create BrowserPlugin as a custom element in order to observe changes var iframeElement = $Document.createElement(document, 'iframe');
// to attributes synchronously.
var browserPluginElement = var style = $HTMLElement.style.get(iframeElement);
new GuestViewContainer[this.viewType + 'BrowserPlugin'](); $Object.defineProperty(style, 'width', {value: '100%'});
privates(browserPluginElement).internal = this; $Object.defineProperty(style, 'height', {value: '100%'});
return browserPluginElement; $Object.defineProperty(style, 'border', {value: '0px'});
return iframeElement;
}; };
GuestViewContainer.prototype.prepareForReattach$ = function() {}; GuestViewContainer.prototype.prepareForReattach = function() {
// Since attachment swaps a local frame for a remote frame, we need our
// internal iframe element to be local again before we can reattach.
var newFrame = this.createInternalElement();
var oldFrame = this.internalElement;
this.internalElement = newFrame;
var frameParent = $Node.parentNode.get(oldFrame);
$Node.replaceChild(frameParent, newFrame, oldFrame);
};
GuestViewContainer.prototype.focus = function() { GuestViewContainer.prototype.focus = function() {
// Focus the internal element when focus() is called on the GuestView element. // Focus the internal element when focus() is called on the GuestView element.
$HTMLElement.focus(this.internalElement); $HTMLElement.focus(this.internalElement);
} }
GuestViewContainer.prototype.attachWindow$ = function() { GuestViewContainer.prototype.attachWindow = function() {
if (!this.internalInstanceId) { var generatedId = IdGenerator.GetNextId();
return true; // Generate an instance id for the container.
} this.onInternalInstanceId(generatedId);
this.guest.attach(this.internalInstanceId,
this.viewInstanceId,
this.buildParams());
return true; return true;
}; };
...@@ -120,15 +123,6 @@ GuestViewContainer.prototype.onInternalInstanceId = function( ...@@ -120,15 +123,6 @@ GuestViewContainer.prototype.onInternalInstanceId = function(
this.buildParams()); this.buildParams());
}; };
GuestViewContainer.prototype.handleInternalElementAttributeMutation =
function(name, oldValue, newValue) {
if (name == 'internalinstanceid' && !oldValue && !!newValue) {
$Element.removeAttribute(
this.internalElement, 'internalinstanceid');
this.onInternalInstanceId($parseInt(newValue));
}
};
GuestViewContainer.prototype.onElementResize = function(newWidth, newHeight) { GuestViewContainer.prototype.onElementResize = function(newWidth, newHeight) {
if (!this.guest.getId()) if (!this.guest.getId())
return; return;
...@@ -167,7 +161,12 @@ GuestViewContainer.prototype.weakWrapper = function(func) { ...@@ -167,7 +161,12 @@ GuestViewContainer.prototype.weakWrapper = function(func) {
}; };
}; };
GuestViewContainer.prototype.willAttachElement$ = function() {}; GuestViewContainer.prototype.willAttachElement = function() {
if (this.deferredAttachCallback) {
this.deferredAttachCallback();
this.deferredAttachCallback = null;
}
};
// Implemented by the specific view type, if needed. // Implemented by the specific view type, if needed.
GuestViewContainer.prototype.buildContainerParams = function() { GuestViewContainer.prototype.buildContainerParams = function() {
......
...@@ -15,61 +15,6 @@ var GuestViewInternalNatives = requireNative('guest_view_internal'); ...@@ -15,61 +15,6 @@ var GuestViewInternalNatives = requireNative('guest_view_internal');
var IdGenerator = requireNative('id_generator'); var IdGenerator = requireNative('id_generator');
var logging = requireNative('logging'); var logging = requireNative('logging');
// Registers the browserplugin and guestview as custom elements.
// |containerElementType| is a GuestViewContainerElement (e.g. WebViewElement)
function registerElement(elementName, containerElementType) {
registerInternalElement($String.toLowerCase(elementName));
registerGuestViewElement(elementName, containerElementType);
}
// Registers the browser plugin <object> custom element. |viewType| is the
// name of the specific guestview container (e.g. 'webview').
function registerInternalElement(viewType) {
GuestViewInternalNatives.AllowGuestViewElementDefinition(() => {
var InternalElement = class extends HTMLObjectElement {
static get observedAttributes() {
return ['internalinstanceid'];
}
constructor() {
super();
$Element.setAttribute(this, 'type', 'application/browser-plugin');
$Element.setAttribute(
this, 'id', 'browser-plugin-' + IdGenerator.GetNextId());
var style = $HTMLElement.style.get(this);
$Object.defineProperty(style, 'width', {value: '100%'});
$Object.defineProperty(style, 'height', {value: '100%'});
}
}
InternalElement.prototype.connectedCallback = function() {
// Load the plugin immediately.
var unused = this.nonExistentAttribute;
};
InternalElement.prototype.attributeChangedCallback = function(
name, oldValue, newValue) {
var internal = privates(this).internal;
if (!internal) {
return;
}
internal.handleInternalElementAttributeMutation(name, oldValue, newValue);
};
$CustomElementRegistry.define(
window.customElements, viewType + 'browserplugin', InternalElement,
{extends: 'object'});
$Object.defineProperty(GuestViewContainer, viewType + 'BrowserPlugin', {
value: InternalElement,
});
delete InternalElement.prototype.connectedCallback;
delete InternalElement.prototype.attributeChangedCallback;
delete InternalElement.observedAttributes;
});
}
// Conceptually, these are methods on GuestViewContainerElement.prototype. // Conceptually, these are methods on GuestViewContainerElement.prototype.
// However, since that is exposed to users, we only set these callbacks on // However, since that is exposed to users, we only set these callbacks on
// the prototype temporarily during the custom element registration. // the prototype temporarily during the custom element registration.
...@@ -80,7 +25,7 @@ var customElementCallbacks = { ...@@ -80,7 +25,7 @@ var customElementCallbacks = {
return; return;
internal.elementAttached = true; internal.elementAttached = true;
internal.willAttachElement$(); internal.willAttachElement();
internal.onElementAttached(); internal.onElementAttached();
}, },
...@@ -105,8 +50,9 @@ var customElementCallbacks = { ...@@ -105,8 +50,9 @@ var customElementCallbacks = {
} }
}; };
// Registers a GuestViewContainerElement as a custom element. // Registers the guestview as a custom element.
function registerGuestViewElement(elementName, containerElementType) { // |containerElementType| is a GuestViewContainerElement (e.g. WebViewElement)
function registerElement(elementName, containerElementType) {
GuestViewInternalNatives.AllowGuestViewElementDefinition(() => { GuestViewInternalNatives.AllowGuestViewElementDefinition(() => {
// We set the lifecycle callbacks so that they're available during // We set the lifecycle callbacks so that they're available during
// registration. Once that's done, we'll delete them so developers cannot // registration. Once that's done, we'll delete them so developers cannot
......
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// GuestViewCrossProcessFrames overrides for guest_view.js.
var $HTMLIFrameElement = require('safeMethods').SafeMethods.$HTMLIFrameElement;
var GuestViewImpl = require('guestView').GuestViewImpl;
var GuestViewInternalNatives = requireNative('guest_view_internal');
var ResizeEvent = require('guestView').ResizeEvent;
var getIframeContentWindow = function(viewInstanceId) {
var view = GuestViewInternalNatives.GetViewFromID(viewInstanceId);
if (!view)
return null;
var internalIframeElement = view.internalElement;
if (internalIframeElement)
return $HTMLIFrameElement.contentWindow.get(internalIframeElement);
return null;
};
// Internal implementation of attach().
GuestViewImpl.prototype.attachImpl$ = function(
internalInstanceId, viewInstanceId, attachParams, callback) {
var view = GuestViewInternalNatives.GetViewFromID(viewInstanceId);
if (!view.elementAttached) {
// Defer the attachment until the <webview> element is attached.
view.deferredAttachCallback = $Function.bind(this.attachImpl$,
this, internalInstanceId, viewInstanceId, attachParams, callback);
return;
};
// Check the current state.
if (!this.checkState('attach')) {
this.handleCallback(callback);
return;
}
// Callback wrapper function to set the contentWindow following attachment,
// and advance the queue.
var callbackWrapper = function(callback) {
var contentWindow = getIframeContentWindow(viewInstanceId);
// Check if attaching failed.
if (!contentWindow) {
this.state = GuestViewImpl.GuestState.GUEST_STATE_CREATED;
this.internalInstanceId = 0;
} else {
// Only update the contentWindow if attaching is successful.
this.contentWindow = contentWindow;
}
this.handleCallback(callback);
};
attachParams['instanceId'] = viewInstanceId;
var contentWindow = getIframeContentWindow(viewInstanceId);
// |contentWindow| is used to retrieve the RenderFrame in cpp.
GuestViewInternalNatives.AttachIframeGuest(
internalInstanceId, this.id, attachParams, contentWindow,
$Function.bind(callbackWrapper, this, callback));
this.internalInstanceId = internalInstanceId;
this.state = GuestViewImpl.GuestState.GUEST_STATE_ATTACHED;
// Detach automatically when the container is destroyed.
GuestViewInternalNatives.RegisterDestructionCallback(
internalInstanceId, this.weakWrapper(function() {
if (this.state != GuestViewImpl.GuestState.GUEST_STATE_ATTACHED ||
this.internalInstanceId != internalInstanceId) {
return;
}
this.internalInstanceId = 0;
this.state = GuestViewImpl.GuestState.GUEST_STATE_CREATED;
}, viewInstanceId));
};
// Internal implementation of create().
GuestViewImpl.prototype.createImpl$ = function(createParams, callback) {
// Check the current state.
if (!this.checkState('create')) {
this.handleCallback(callback);
return;
}
// Callback wrapper function to store the guestInstanceId from the
// createGuest() callback, handle potential creation failure, and advance the
// queue.
var callbackWrapper = function(callback, guestInfo) {
this.id = guestInfo.id;
// Check if creation failed.
if (this.id === 0) {
this.state = GuestViewImpl.GuestState.GUEST_STATE_START;
this.contentWindow = null;
}
ResizeEvent.addListener(this.callOnResize, {instanceId: this.id});
this.handleCallback(callback);
};
this.sendCreateRequest(
createParams, $Function.bind(callbackWrapper, this, callback));
this.state = GuestViewImpl.GuestState.GUEST_STATE_CREATED;
};
// Internal implementation of destroy().
GuestViewImpl.prototype.destroyImpl$ = function(callback) {
// Check the current state.
if (!this.checkState('destroy')) {
this.handleCallback(callback);
return;
}
if (this.state == GuestViewImpl.GuestState.GUEST_STATE_START) {
// destroy() does nothing in this case.
this.handleCallback(callback);
return;
}
// Reset the state of the destroyed guest;
this.contentWindow = null;
this.id = 0;
this.internalInstanceId = 0;
this.state = GuestViewImpl.GuestState.GUEST_STATE_START;
if (ResizeEvent.hasListener(this.callOnResize)) {
ResizeEvent.removeListener(this.callOnResize);
}
// Handle callback at end to avoid handling items in the action queue out of
// order, since the callback is run synchronously here.
this.handleCallback(callback);
};
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// GuestViewCrossProcessFrames overrides for guest_view_container.js
var $Document = require('safeMethods').SafeMethods.$Document;
var $HTMLElement = require('safeMethods').SafeMethods.$HTMLElement;
var $Node = require('safeMethods').SafeMethods.$Node;
var GuestViewContainer = require('guestViewContainer').GuestViewContainer;
var IdGenerator = requireNative('id_generator');
GuestViewContainer.prototype.createInternalElement$ = function() {
var iframeElement = $Document.createElement(document, 'iframe');
var style = $HTMLElement.style.get(iframeElement);
$Object.defineProperty(style, 'width', {value: '100%'});
$Object.defineProperty(style, 'height', {value: '100%'});
$Object.defineProperty(style, 'border', {value: '0px'});
return iframeElement;
};
GuestViewContainer.prototype.prepareForReattach$ = function() {
// Since attachment swaps a local frame for a remote frame, we need our
// internal iframe element to be local again before we can reattach.
var newFrame = this.createInternalElement$();
var oldFrame = this.internalElement;
this.internalElement = newFrame;
var frameParent = $Node.parentNode.get(oldFrame);
$Node.replaceChild(frameParent, newFrame, oldFrame);
};
GuestViewContainer.prototype.attachWindow$ = function() {
var generatedId = IdGenerator.GetNextId();
// Generate an instance id for the container.
this.onInternalInstanceId(generatedId);
return true;
};
GuestViewContainer.prototype.willAttachElement$ = function() {
if (this.deferredAttachCallback) {
this.deferredAttachCallback();
this.deferredAttachCallback = null;
}
};
...@@ -131,7 +131,7 @@ WebViewImpl.prototype.onSizeChanged = function(webViewEvent) { ...@@ -131,7 +131,7 @@ WebViewImpl.prototype.onSizeChanged = function(webViewEvent) {
WebViewImpl.prototype.createGuest = function() { WebViewImpl.prototype.createGuest = function() {
this.guest.create(this.buildParams(), $Function.bind(function() { this.guest.create(this.buildParams(), $Function.bind(function() {
this.attachWindow$(); this.attachWindow();
}, this)); }, this));
}; };
...@@ -173,7 +173,7 @@ WebViewImpl.prototype.buildContainerParams = function() { ...@@ -173,7 +173,7 @@ WebViewImpl.prototype.buildContainerParams = function() {
return params; return params;
}; };
WebViewImpl.prototype.attachWindow$ = function(opt_guestInstanceId) { WebViewImpl.prototype.attachWindow = function(opt_guestInstanceId) {
// If |opt_guestInstanceId| was provided, then a different existing guest is // If |opt_guestInstanceId| was provided, then a different existing guest is
// being attached to this webview, and the current one will get destroyed. // being attached to this webview, and the current one will get destroyed.
if (opt_guestInstanceId) { if (opt_guestInstanceId) {
...@@ -182,10 +182,10 @@ WebViewImpl.prototype.attachWindow$ = function(opt_guestInstanceId) { ...@@ -182,10 +182,10 @@ WebViewImpl.prototype.attachWindow$ = function(opt_guestInstanceId) {
} }
this.guest.destroy(); this.guest.destroy();
this.guest = new GuestView('webview', opt_guestInstanceId); this.guest = new GuestView('webview', opt_guestInstanceId);
this.prepareForReattach$(); this.prepareForReattach();
} }
return $Function.call(GuestViewContainer.prototype.attachWindow$, this); return $Function.call(GuestViewContainer.prototype.attachWindow, this);
}; };
// Shared implementation of executeScript() and insertCSS(). // Shared implementation of executeScript() and insertCSS().
......
...@@ -194,7 +194,7 @@ NewWindow.prototype.getInterfaceObject = function() { ...@@ -194,7 +194,7 @@ NewWindow.prototype.getInterfaceObject = function() {
webViewImpl.onAttach(this.event.partition); webViewImpl.onAttach(this.event.partition);
} }
var attached = webViewImpl.attachWindow$(this.event.windowId); var attached = webViewImpl.attachWindow(this.event.windowId);
if (!attached) { if (!attached) {
window.console.error(ERROR_MSG_NEWWINDOW_UNABLE_TO_ATTACH); window.console.error(ERROR_MSG_NEWWINDOW_UNABLE_TO_ATTACH);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment