| Index: chrome/renderer/resources/extensions/web_view.js
|
| diff --git a/chrome/renderer/resources/extensions/web_view.js b/chrome/renderer/resources/extensions/web_view.js
|
| index a21a4ab5de093d81d49fac130a7dfa38f2ef5398..5f0cb6e5890750dd02b98e6c8e56e03c63127b90 100644
|
| --- a/chrome/renderer/resources/extensions/web_view.js
|
| +++ b/chrome/renderer/resources/extensions/web_view.js
|
| @@ -14,6 +14,7 @@ var IdGenerator = requireNative('id_generator');
|
| // something else.
|
| var WebView = require('webViewInternal').WebView;
|
| var WebViewEvents = require('webViewEvents').WebViewEvents;
|
| +var guestViewInternalNatives = requireNative('guest_view_internal');
|
|
|
| var WEB_VIEW_ATTRIBUTE_AUTOSIZE = 'autosize';
|
| var WEB_VIEW_ATTRIBUTE_MAXHEIGHT = 'maxheight';
|
| @@ -30,8 +31,6 @@ var AUTO_SIZE_ATTRIBUTES = [
|
|
|
| var WEB_VIEW_ATTRIBUTE_PARTITION = 'partition';
|
|
|
| -var PLUGIN_METHOD_ATTACH = '-internal-attach';
|
| -
|
| var ERROR_MSG_ALREADY_NAVIGATED =
|
| 'The object has already navigated, so its partition cannot be changed.';
|
| var ERROR_MSG_INVALID_PARTITION_ATTRIBUTE = 'Invalid partition attribute.';
|
| @@ -149,18 +148,27 @@ WebViewInternal.prototype.createBrowserPluginNode = function() {
|
| return browserPluginNode;
|
| };
|
|
|
| -WebViewInternal.prototype.getInstanceId = function() {
|
| - return this.instanceId;
|
| +WebViewInternal.prototype.getGuestInstanceId = function() {
|
| + return this.guestInstanceId;
|
| };
|
|
|
| /**
|
| * Resets some state upon reattaching <webview> element to the DOM.
|
| */
|
| -WebViewInternal.prototype.resetUponReattachment = function() {
|
| - this.instanceId = undefined;
|
| - this.beforeFirstNavigation = true;
|
| - this.validPartitionId = true;
|
| - this.partition.validPartitionId = true;
|
| +WebViewInternal.prototype.reset = function() {
|
| + // If guestInstanceId is defined then the <webview> has navigated and has
|
| + // already picked up a partition ID. Thus, we need to reset the initialization
|
| + // state. However, it may be the case that beforeFirstNavigation is false BUT
|
| + // guestInstanceId has yet to be initialized. This means that we have not
|
| + // heard back from createGuest yet. We will not reset the flag in this case so
|
| + // that we don't end up allocating a second guest.
|
| + if (this.guestInstanceId) {
|
| + this.guestInstanceId = undefined;
|
| + this.beforeFirstNavigation = true;
|
| + this.validPartitionId = true;
|
| + this.partition.validPartitionId = true;
|
| + }
|
| + this.internalInstanceId = 0;
|
| };
|
|
|
| // Sets <webview>.request property.
|
| @@ -227,10 +235,10 @@ WebViewInternal.prototype.canGoForward = function() {
|
| * @private
|
| */
|
| WebViewInternal.prototype.clearData = function() {
|
| - if (!this.instanceId) {
|
| + if (!this.guestInstanceId) {
|
| return;
|
| }
|
| - var args = $Array.concat([this.instanceId], $Array.slice(arguments));
|
| + var args = $Array.concat([this.guestInstanceId], $Array.slice(arguments));
|
| $Function.apply(WebView.clearData, null, args);
|
| };
|
|
|
| @@ -245,10 +253,10 @@ WebViewInternal.prototype.getProcessId = function() {
|
| * @private
|
| */
|
| WebViewInternal.prototype.go = function(relativeIndex) {
|
| - if (!this.instanceId) {
|
| + if (!this.guestInstanceId) {
|
| return;
|
| }
|
| - WebView.go(this.instanceId, relativeIndex);
|
| + WebView.go(this.guestInstanceId, relativeIndex);
|
| };
|
|
|
| /**
|
| @@ -262,30 +270,30 @@ WebViewInternal.prototype.print = function() {
|
| * @private
|
| */
|
| WebViewInternal.prototype.reload = function() {
|
| - if (!this.instanceId) {
|
| + if (!this.guestInstanceId) {
|
| return;
|
| }
|
| - WebView.reload(this.instanceId);
|
| + WebView.reload(this.guestInstanceId);
|
| };
|
|
|
| /**
|
| * @private
|
| */
|
| WebViewInternal.prototype.stop = function() {
|
| - if (!this.instanceId) {
|
| + if (!this.guestInstanceId) {
|
| return;
|
| }
|
| - WebView.stop(this.instanceId);
|
| + WebView.stop(this.guestInstanceId);
|
| };
|
|
|
| /**
|
| * @private
|
| */
|
| WebViewInternal.prototype.terminate = function() {
|
| - if (!this.instanceId) {
|
| + if (!this.guestInstanceId) {
|
| return;
|
| }
|
| - WebView.terminate(this.instanceId);
|
| + WebView.terminate(this.guestInstanceId);
|
| };
|
|
|
| /**
|
| @@ -294,7 +302,7 @@ WebViewInternal.prototype.terminate = function() {
|
| WebViewInternal.prototype.validateExecuteCodeCall = function() {
|
| var ERROR_MSG_CANNOT_INJECT_SCRIPT = '<webview>: ' +
|
| 'Script cannot be injected into content until the page has loaded.';
|
| - if (!this.instanceId) {
|
| + if (!this.guestInstanceId) {
|
| throw new Error(ERROR_MSG_CANNOT_INJECT_SCRIPT);
|
| }
|
| };
|
| @@ -304,7 +312,7 @@ WebViewInternal.prototype.validateExecuteCodeCall = function() {
|
| */
|
| WebViewInternal.prototype.executeScript = function(var_args) {
|
| this.validateExecuteCodeCall();
|
| - var args = $Array.concat([this.instanceId, this.src],
|
| + var args = $Array.concat([this.guestInstanceId, this.src],
|
| $Array.slice(arguments));
|
| $Function.apply(WebView.executeScript, null, args);
|
| };
|
| @@ -314,7 +322,7 @@ WebViewInternal.prototype.executeScript = function(var_args) {
|
| */
|
| WebViewInternal.prototype.insertCSS = function(var_args) {
|
| this.validateExecuteCodeCall();
|
| - var args = $Array.concat([this.instanceId, this.src],
|
| + var args = $Array.concat([this.guestInstanceId, this.src],
|
| $Array.slice(arguments));
|
| $Function.apply(WebView.insertCSS, null, args);
|
| };
|
| @@ -469,12 +477,12 @@ WebViewInternal.prototype.handleWebviewAttributeMutation =
|
| // details.
|
| if (AUTO_SIZE_ATTRIBUTES.indexOf(name) > -1) {
|
| this[name] = newValue;
|
| - if (!this.instanceId) {
|
| + if (!this.guestInstanceId) {
|
| return;
|
| }
|
| // Convert autosize attribute to boolean.
|
| var autosize = this.webviewNode.hasAttribute(WEB_VIEW_ATTRIBUTE_AUTOSIZE);
|
| - GuestViewInternal.setAutoSize(this.instanceId, {
|
| + GuestViewInternal.setAutoSize(this.guestInstanceId, {
|
| 'enableAutoSize': autosize,
|
| 'min': {
|
| 'width': parseInt(this.minwidth || 0),
|
| @@ -496,10 +504,10 @@ WebViewInternal.prototype.handleWebviewAttributeMutation =
|
| return;
|
| }
|
| this.name = newValue;
|
| - if (!this.instanceId) {
|
| + if (!this.guestInstanceId) {
|
| return;
|
| }
|
| - WebView.setName(this.instanceId, newValue);
|
| + WebView.setName(this.guestInstanceId, newValue);
|
| return;
|
| } else if (name == 'src') {
|
| // We treat null attribute (attribute removed) and the empty string as
|
| @@ -552,20 +560,20 @@ WebViewInternal.prototype.handleWebviewAttributeMutation =
|
| */
|
| WebViewInternal.prototype.handleBrowserPluginAttributeMutation =
|
| function(name, oldValue, newValue) {
|
| - if (name == 'internalbindings' && !oldValue && newValue) {
|
| - this.browserPluginNode.removeAttribute('internalbindings');
|
| -
|
| - if (this.deferredAttachState) {
|
| - var self = this;
|
| - // A setTimeout is necessary for the binding to be initialized properly.
|
| + if (name == 'internalinstanceid' && !oldValue && !!newValue) {
|
| + this.browserPluginNode.removeAttribute('internalinstanceid');
|
| + this.internalInstanceId = parseInt(newValue);
|
| + if (this.deferredAttachState && !!this.guestInstanceId &&
|
| + this.guestInstanceId != 0) {
|
| window.setTimeout(function() {
|
| - if (self.hasBindings()) {
|
| - var params = self.buildAttachParams(
|
| - self.deferredAttachState.isNewWindow);
|
| - self.browserPluginNode[PLUGIN_METHOD_ATTACH](self.instanceId, params);
|
| - self.deferredAttachState = null;
|
| - }
|
| - }, 0);
|
| + var isNewWindow = this.deferredAttachState ?
|
| + this.deferredAttachState.isNewWindow : false;
|
| + var params = this.buildAttachParams(isNewWindow);
|
| + guestViewInternalNatives.AttachGuest(
|
| + this.internalInstanceId,
|
| + this.guestInstanceId,
|
| + params);
|
| + }.bind(this), 0);
|
| }
|
| return;
|
| }
|
| @@ -652,10 +660,9 @@ WebViewInternal.prototype.onSizeChanged = function(webViewEvent) {
|
| }
|
| };
|
|
|
| -// Returns true if Browser Plugin bindings is available.
|
| -// Bindings are unavailable if <object> is not in the render tree.
|
| -WebViewInternal.prototype.hasBindings = function() {
|
| - return 'function' == typeof this.browserPluginNode[PLUGIN_METHOD_ATTACH];
|
| +// Returns if <object> is in the render tree.
|
| +WebViewInternal.prototype.isPluginInRenderTree = function() {
|
| + return !!this.internalInstanceId && this.internalInstanceId != 0;
|
| };
|
|
|
| WebViewInternal.prototype.hasNavigated = function() {
|
| @@ -687,7 +694,7 @@ WebViewInternal.prototype.parseSrcAttribute = function(result) {
|
| }
|
|
|
| // Navigate to this.src.
|
| - WebView.navigate(this.instanceId, this.src);
|
| + WebView.navigate(this.guestInstanceId, this.src);
|
| return true;
|
| };
|
|
|
| @@ -700,7 +707,7 @@ WebViewInternal.prototype.parseAttributes = function() {
|
| };
|
|
|
| WebViewInternal.prototype.hasGuestInstanceID = function() {
|
| - return this.instanceId != undefined;
|
| + return this.guestInstanceId != undefined;
|
| };
|
|
|
| WebViewInternal.prototype.allocateInstanceId = function() {
|
| @@ -714,10 +721,10 @@ WebViewInternal.prototype.allocateInstanceId = function() {
|
| GuestViewInternal.createGuest(
|
| 'webview',
|
| params,
|
| - function(instanceId) {
|
| + function(guestInstanceId) {
|
| // TODO(lazyboy): Make sure this.autoNavigate_ stuff correctly updated
|
| // |self.src| at this point.
|
| - self.attachWindow(instanceId, false);
|
| + self.attachWindow(guestInstanceId, false);
|
| });
|
| };
|
|
|
| @@ -794,43 +801,43 @@ WebViewInternal.prototype.isUserAgentOverridden = function() {
|
| /** @private */
|
| WebViewInternal.prototype.setUserAgentOverride = function(userAgentOverride) {
|
| this.userAgentOverride = userAgentOverride;
|
| - if (!this.instanceId) {
|
| + if (!this.guestInstanceId) {
|
| // If we are not attached yet, then we will pick up the user agent on
|
| // attachment.
|
| return;
|
| }
|
| - WebView.overrideUserAgent(this.instanceId, userAgentOverride);
|
| + WebView.overrideUserAgent(this.guestInstanceId, userAgentOverride);
|
| };
|
|
|
| /** @private */
|
| WebViewInternal.prototype.find = function(search_text, options, callback) {
|
| - if (!this.instanceId) {
|
| + if (!this.guestInstanceId) {
|
| return;
|
| }
|
| - WebView.find(this.instanceId, search_text, options, callback);
|
| + WebView.find(this.guestInstanceId, search_text, options, callback);
|
| };
|
|
|
| /** @private */
|
| WebViewInternal.prototype.stopFinding = function(action) {
|
| - if (!this.instanceId) {
|
| + if (!this.guestInstanceId) {
|
| return;
|
| }
|
| - WebView.stopFinding(this.instanceId, action);
|
| + WebView.stopFinding(this.guestInstanceId, action);
|
| };
|
|
|
| /** @private */
|
| WebViewInternal.prototype.setZoom = function(zoomFactor, callback) {
|
| - if (!this.instanceId) {
|
| + if (!this.guestInstanceId) {
|
| return;
|
| }
|
| - WebView.setZoom(this.instanceId, zoomFactor, callback);
|
| + WebView.setZoom(this.guestInstanceId, zoomFactor, callback);
|
| };
|
|
|
| WebViewInternal.prototype.getZoom = function(callback) {
|
| - if (!this.instanceId) {
|
| + if (!this.guestInstanceId) {
|
| return;
|
| }
|
| - WebView.getZoom(this.instanceId, callback);
|
| + WebView.getZoom(this.guestInstanceId, callback);
|
| };
|
|
|
| WebViewInternal.prototype.buildAttachParams = function(isNewWindow) {
|
| @@ -852,19 +859,21 @@ WebViewInternal.prototype.buildAttachParams = function(isNewWindow) {
|
| return params;
|
| };
|
|
|
| -WebViewInternal.prototype.attachWindow = function(instanceId, isNewWindow) {
|
| - this.instanceId = instanceId;
|
| +WebViewInternal.prototype.attachWindow = function(guestInstanceId,
|
| + isNewWindow) {
|
| + this.guestInstanceId = guestInstanceId;
|
| var params = this.buildAttachParams(isNewWindow);
|
|
|
| - if (!this.hasBindings()) {
|
| - // No bindings means that the plugin isn't there (display: none), we defer
|
| - // attachWindow in this case.
|
| + if (!this.isPluginInRenderTree()) {
|
| this.deferredAttachState = {isNewWindow: isNewWindow};
|
| return false;
|
| }
|
|
|
| this.deferredAttachState = null;
|
| - return this.browserPluginNode[PLUGIN_METHOD_ATTACH](this.instanceId, params);
|
| + return guestViewInternalNatives.AttachGuest(
|
| + this.internalInstanceId,
|
| + this.guestInstanceId,
|
| + params);
|
| };
|
|
|
| // Registers browser plugin <object> custom element.
|
| @@ -873,6 +882,7 @@ function registerBrowserPluginElement() {
|
|
|
| proto.createdCallback = function() {
|
| this.setAttribute('type', 'application/browser-plugin');
|
| + this.setAttribute('id', 'browser-plugin-' + IdGenerator.GetNextId());
|
| // The <object> node fills in the <webview> container.
|
| this.style.width = '100%';
|
| this.style.height = '100%';
|
| @@ -923,6 +933,7 @@ function registerWebViewElement() {
|
| return;
|
| }
|
| internal.elementAttached = false;
|
| + internal.reset();
|
| };
|
|
|
| proto.attachedCallback = function() {
|
| @@ -932,7 +943,6 @@ function registerWebViewElement() {
|
| }
|
| if (!internal.elementAttached) {
|
| internal.elementAttached = true;
|
| - internal.resetUponReattachment();
|
| internal.parseAttributes();
|
| }
|
| };
|
| @@ -1019,7 +1029,7 @@ WebViewInternal.prototype.maybeHandleContextMenu = function(e, webViewEvent) {
|
| // Setting |params| = undefined will show the context menu unmodified, hence
|
| // the 'contextmenu' API is disabled for stable channel.
|
| var params = undefined;
|
| - WebView.showContextMenu(this.instanceId, requestId, params);
|
| + WebView.showContextMenu(this.guestInstanceId, requestId, params);
|
| };
|
|
|
| /**
|
|
|