Commit 617e4fc4 authored by ericzeng's avatar ericzeng Committed by Commit bot

Implement <extensionoptions> deferred attach logic

Due to how the browser plugin is created, it is possible for the
<extensionoptions> element to attempt to attach to the embedder before
the browser plugin has bindings. This occurs when an ExtensionOptions object
gets an extension id and creates a guest, but has not yet been added
to the DOM. Use the deferred attach logic from <webview> so that if this
case occurs, wait until the browser plugin gets its bindings before
trying to attach the guest view.

BUG=386838

Review URL: https://codereview.chromium.org/457653003

Cr-Commit-Position: refs/heads/master@{#292215}
parent 9a44f044
...@@ -35,29 +35,31 @@ function ExtensionOptionsInternal(extensionoptionsNode) { ...@@ -35,29 +35,31 @@ function ExtensionOptionsInternal(extensionoptionsNode) {
// the event is fired from here instead of through // the event is fired from here instead of through
// extension_options_events.js. // extension_options_events.js.
this.setupEventProperty('createfailed'); this.setupEventProperty('createfailed');
new ExtensionOptionsEvents(this, this.viewInstanceId); new ExtensionOptionsEvents(this, this.viewInstanceId);
this.setupNodeProperties(); this.setupNodeProperties();
if (this.parseExtensionAttribute()) this.parseExtensionAttribute();
this.init();
// Once the browser plugin has been created, the guest view will be created
// and attached. See handleBrowserPluginAttributeMutation().
this.browserPluginNode = this.createBrowserPluginNode();
var shadowRoot = this.extensionoptionsNode.createShadowRoot();
shadowRoot.appendChild(this.browserPluginNode);
}; };
ExtensionOptionsInternal.prototype.attachWindow = function(guestInstanceId) { ExtensionOptionsInternal.prototype.attachWindow = function() {
this.guestInstanceId = guestInstanceId; return guestViewInternalNatives.AttachGuest(
var params = { this.internalInstanceId,
this.guestInstanceId,
{
'autosize': this.autosize, 'autosize': this.autosize,
'instanceId': this.viewInstanceId, 'instanceId': this.viewInstanceId,
'maxheight': parseInt(this.maxheight || 0), 'maxheight': parseInt(this.maxheight || 0),
'maxwidth': parseInt(this.maxwidth || 0), 'maxwidth': parseInt(this.maxwidth || 0),
'minheight': parseInt(this.minheight || 0), 'minheight': parseInt(this.minheight || 0),
'minwidth': parseInt(this.minwidth || 0) 'minwidth': parseInt(this.minwidth || 0)
}; });
return guestViewInternalNatives.AttachGuest(
parseInt(this.browserPluginNode.getAttribute('internalinstanceid')),
guestInstanceId,
params);
}; };
ExtensionOptionsInternal.prototype.createBrowserPluginNode = function() { ExtensionOptionsInternal.prototype.createBrowserPluginNode = function() {
...@@ -81,7 +83,8 @@ ExtensionOptionsInternal.prototype.createGuest = function() { ...@@ -81,7 +83,8 @@ ExtensionOptionsInternal.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(guestInstanceId); this.guestInstanceId = guestInstanceId;
this.attachWindow();
} }
}.bind(this)); }.bind(this));
}; };
...@@ -101,11 +104,18 @@ ExtensionOptionsInternal.prototype.handleExtensionOptionsAttributeMutation = ...@@ -101,11 +104,18 @@ ExtensionOptionsInternal.prototype.handleExtensionOptionsAttributeMutation =
if (oldValue === newValue) if (oldValue === newValue)
return; return;
if (name == 'extension') { if (name == 'extension' && !oldValue && newValue) {
this.extensionId = newValue; this.extensionId = newValue;
// Create new guest view if one hasn't been created for this element. // If the browser plugin is not ready then don't create the guest until
if (!this.guestInstanceId && this.parseExtensionAttribute()) // it is ready (in handleBrowserPluginAttributeMutation).
this.init(); if (!this.internalInstanceId)
return;
// If a guest view does not exist then create one.
if (!this.guestInstanceId) {
this.createGuest();
return;
}
// TODO(ericzeng): Implement navigation to another guest view if we want // TODO(ericzeng): Implement navigation to another guest view if we want
// that functionality. // that functionality.
} else if (AUTO_SIZE_ATTRIBUTES.hasOwnProperty(name) > -1) { } else if (AUTO_SIZE_ATTRIBUTES.hasOwnProperty(name) > -1) {
...@@ -129,15 +139,15 @@ ExtensionOptionsInternal.prototype.handleExtensionOptionsAttributeMutation = ...@@ -129,15 +139,15 @@ ExtensionOptionsInternal.prototype.handleExtensionOptionsAttributeMutation =
} }
}; };
ExtensionOptionsInternal.prototype.init = function() { ExtensionOptionsInternal.prototype.handleBrowserPluginAttributeMutation =
if (this.initCalled) function(name, oldValue, newValue) {
return; if (name == 'internalinstanceid' && !oldValue && !!newValue) {
this.internalInstanceId = parseInt(newValue);
this.initCalled = true; this.browserPluginNode.removeAttribute('internalinstanceid');
this.browserPluginNode = this.createBrowserPluginNode(); if (this.extensionId)
var shadowRoot = this.extensionoptionsNode.createShadowRoot();
shadowRoot.appendChild(this.browserPluginNode);
this.createGuest(); this.createGuest();
}
}; };
ExtensionOptionsInternal.prototype.onSizeChanged = ExtensionOptionsInternal.prototype.onSizeChanged =
...@@ -292,6 +302,14 @@ function registerBrowserPluginElement() { ...@@ -292,6 +302,14 @@ function registerBrowserPluginElement() {
this.style.height = '100%'; this.style.height = '100%';
}; };
proto.attributeChangedCallback = function(name, oldValue, newValue) {
var internal = privates(this).internal;
if (!internal) {
return;
}
internal.handleBrowserPluginAttributeMutation(name, oldValue, newValue);
};
proto.attachedCallback = function() { proto.attachedCallback = function() {
// Load the plugin immediately. // Load the plugin immediately.
var unused = this.nonExistentAttribute; var unused = this.nonExistentAttribute;
......
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