Commit 5483c541 authored by Kevin McNee's avatar Kevin McNee Committed by Commit Bot

Eliminate several circular dependencies in guest view js

In the guest view js implementation, setupAttributes and getApiMethods
both form circular dependencies.

Bug: 793935
Change-Id: I1118e03daea247e3ea670b6bee3788ba9558d779
Reviewed-on: https://chromium-review.googlesource.com/1177841Reviewed-by: default avatarPaul Meyer <paulmeyer@chromium.org>
Commit-Queue: Kevin McNee <mcnee@chromium.org>
Cr-Commit-Position: refs/heads/master@{#585521}
parent ebbac47d
......@@ -6,6 +6,8 @@ var ExtensionOptionsConstants =
require('extensionOptionsConstants').ExtensionOptionsConstants;
var ExtensionOptionsEvents =
require('extensionOptionsEvents').ExtensionOptionsEvents;
var ExtensionOptionsAttributes =
require('extensionOptionsAttributes').ExtensionOptionsAttributes;
var GuestViewContainer = require('guestViewContainer').GuestViewContainer;
function ExtensionOptionsImpl(extensionoptionsElement) {
......@@ -21,7 +23,13 @@ ExtensionOptionsImpl.VIEW_TYPE = 'ExtensionOptions';
ExtensionOptionsImpl.prototype.onElementAttached = function() {
this.createGuest();
}
};
// Sets up all of the extensionoptions attributes.
ExtensionOptionsImpl.prototype.setupAttributes = function() {
this.attributes[ExtensionOptionsConstants.ATTRIBUTE_EXTENSION] =
new ExtensionOptionsAttributes.ExtensionAttribute(this);
};
ExtensionOptionsImpl.prototype.buildContainerParams = function() {
var params = {};
......@@ -48,6 +56,3 @@ ExtensionOptionsImpl.prototype.createGuest = function() {
};
GuestViewContainer.registerElement(ExtensionOptionsImpl);
// Exports.
exports.$set('ExtensionOptionsImpl', ExtensionOptionsImpl);
......@@ -7,7 +7,6 @@
var GuestViewAttributes = require('guestViewAttributes').GuestViewAttributes;
var ExtensionOptionsConstants =
require('extensionOptionsConstants').ExtensionOptionsConstants;
var ExtensionOptionsImpl = require('extensionOptions').ExtensionOptionsImpl;
// -----------------------------------------------------------------------------
// ExtensionAttribute object.
......@@ -35,10 +34,7 @@ ExtensionAttribute.prototype.handleMutation = function(oldValue, newValue) {
this.view.createGuest();
};
// -----------------------------------------------------------------------------
var ExtensionOptionsAttributes = {ExtensionAttribute: ExtensionAttribute};
// Sets up all of the extensionoptions attributes.
ExtensionOptionsImpl.prototype.setupAttributes = function() {
this.attributes[ExtensionOptionsConstants.ATTRIBUTE_EXTENSION] =
new ExtensionAttribute(this);
};
// Exports.
exports.$set('ExtensionOptionsAttributes', ExtensionOptionsAttributes);
......@@ -7,6 +7,10 @@
var GuestViewContainer = require('guestViewContainer').GuestViewContainer;
var ExtensionViewConstants =
require('extensionViewConstants').ExtensionViewConstants;
var EXTENSION_VIEW_API_METHODS =
require('extensionViewApiMethods').EXTENSION_VIEW_API_METHODS;
var ExtensionViewAttributes =
require('extensionViewAttributes').ExtensionViewAttributes;
var ExtensionViewEvents = require('extensionViewEvents').ExtensionViewEvents;
var ExtensionViewInternal = getInternalApi ?
getInternalApi('extensionViewInternal') :
......@@ -33,9 +37,7 @@ ExtensionViewImpl.prototype.__proto__ = GuestViewContainer.prototype;
ExtensionViewImpl.VIEW_TYPE = 'ExtensionView';
ExtensionViewImpl.setupElement = function(proto) {
var apiMethods = ExtensionViewImpl.getApiMethods();
GuestViewContainer.forwardApiMethods(proto, apiMethods);
GuestViewContainer.forwardApiMethods(proto, EXTENSION_VIEW_API_METHODS);
};
ExtensionViewImpl.prototype.createGuest = function(callback) {
......@@ -53,6 +55,14 @@ ExtensionViewImpl.prototype.buildContainerParams = function() {
return params;
};
// Sets up all of the extensionview attributes.
ExtensionViewImpl.prototype.setupAttributes = function() {
this.attributes[ExtensionViewConstants.ATTRIBUTE_EXTENSION] =
new ExtensionViewAttributes.ExtensionAttribute(this);
this.attributes[ExtensionViewConstants.ATTRIBUTE_SRC] =
new ExtensionViewAttributes.SrcAttribute(this);
};
ExtensionViewImpl.prototype.onElementDetached = function() {
this.guest.destroy();
......@@ -136,7 +146,18 @@ ExtensionViewImpl.prototype.loadNextSrc = function() {
}
};
GuestViewContainer.registerElement(ExtensionViewImpl);
ExtensionViewImpl.prototype.load = function(src) {
return new Promise($Function.bind(function(resolve, reject) {
$Array.push(this.loadQueue, {src: src, resolve: resolve, reject: reject});
this.loadNextSrc();
}, this)).then($Function.bind(function onLoadResolved() {
this.pendingLoad = null;
this.loadNextSrc();
}, this), $Function.bind(function onLoadRejected(reason) {
this.pendingLoad = null;
this.loadNextSrc();
return Promise.reject(reason);
}, this));
};
// Exports.
exports.$set('ExtensionViewImpl', ExtensionViewImpl);
GuestViewContainer.registerElement(ExtensionViewImpl);
......@@ -2,17 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// This module implements the public-facing API functions for the
// This module contains the public-facing API functions for the
// <extensionview> tag.
var ExtensionViewInternal = getInternalApi ?
getInternalApi('extensionViewInternal') :
require('extensionViewInternal').ExtensionViewInternal;
var ExtensionViewImpl = require('extensionView').ExtensionViewImpl;
var ExtensionViewConstants =
require('extensionViewConstants').ExtensionViewConstants;
// An array of <extensionview>'s public-facing API methods.
var EXTENSION_VIEW_API_METHODS = [
// Loads the given src into extensionview. Must be called every time the
// the extensionview should load a new page. This is the only way to set
......@@ -21,26 +13,5 @@ var EXTENSION_VIEW_API_METHODS = [
'load'
];
// -----------------------------------------------------------------------------
// Custom API method implementations.
ExtensionViewImpl.prototype.load = function(src) {
return new Promise($Function.bind(function(resolve, reject) {
$Array.push(this.loadQueue, {src: src, resolve: resolve, reject: reject});
this.loadNextSrc();
}, this))
.then($Function.bind(function onLoadResolved() {
this.pendingLoad = null;
this.loadNextSrc();
}, this), $Function.bind(function onLoadRejected(reason) {
this.pendingLoad = null;
this.loadNextSrc();
return Promise.reject(reason);
}, this));
};
// -----------------------------------------------------------------------------
ExtensionViewImpl.getApiMethods = function() {
return EXTENSION_VIEW_API_METHODS;
};
// Exports.
exports.$set('EXTENSION_VIEW_API_METHODS', EXTENSION_VIEW_API_METHODS);
......@@ -7,10 +7,6 @@
var GuestViewAttributes = require('guestViewAttributes').GuestViewAttributes;
var ExtensionViewConstants =
require('extensionViewConstants').ExtensionViewConstants;
var ExtensionViewImpl = require('extensionView').ExtensionViewImpl;
var ExtensionViewInternal = getInternalApi ?
getInternalApi('extensionViewInternal') :
require('extensionViewInternal').ExtensionViewInternal;
// -----------------------------------------------------------------------------
// ExtensionAttribute object.
......@@ -45,14 +41,12 @@ SrcAttribute.prototype.handleMutation = function(oldValue, newValue) {
console.log('src is read only. Use .load(url) to navigate to a new ' +
'extension page.');
this.setValueIgnoreMutation(oldValue);
}
// -----------------------------------------------------------------------------
};
// Sets up all of the extensionview attributes.
ExtensionViewImpl.prototype.setupAttributes = function() {
this.attributes[ExtensionViewConstants.ATTRIBUTE_EXTENSION] =
new ExtensionAttribute(this);
this.attributes[ExtensionViewConstants.ATTRIBUTE_SRC] =
new SrcAttribute(this);
var ExtensionViewAttributes = {
ExtensionAttribute: ExtensionAttribute,
SrcAttribute: SrcAttribute
};
// Exports.
exports.$set('ExtensionViewAttributes', ExtensionViewAttributes);
......@@ -11,6 +11,8 @@ var GuestView = require('guestView').GuestView;
var GuestViewContainer = require('guestViewContainer').GuestViewContainer;
var GuestViewInternalNatives = requireNative('guest_view_internal');
var WebViewConstants = require('webViewConstants').WebViewConstants;
var WEB_VIEW_API_METHODS = require('webViewApiMethods').WEB_VIEW_API_METHODS;
var WebViewAttributes = require('webViewAttributes').WebViewAttributes;
var WebViewEvents = require('webViewEvents').WebViewEvents;
var WebViewInternal = getInternalApi ?
getInternalApi('webViewInternal') :
......@@ -30,29 +32,33 @@ WebViewImpl.VIEW_TYPE = 'WebView';
// Add extra functionality to |this.element|.
WebViewImpl.setupElement = function(proto) {
// Public-facing API methods.
var apiMethods = WebViewImpl.getApiMethods();
// Forward proto.foo* method calls to WebViewImpl.foo*.
GuestViewContainer.forwardApiMethods(proto, WEB_VIEW_API_METHODS);
};
// Create default implementations for undefined API methods.
var createDefaultApiMethod = function(m) {
return function(var_args) {
if (!this.guest.getId()) {
return false;
}
var args = $Array.concat([this.guest.getId()], $Array.slice(arguments));
$Function.apply(WebViewInternal[m], null, args);
return true;
};
};
for (var i = 0; i != apiMethods.length; ++i) {
if (WebViewImpl.prototype[apiMethods[i]] == undefined) {
WebViewImpl.prototype[apiMethods[i]] =
createDefaultApiMethod(apiMethods[i]);
}
// Sets up all of the webview attributes.
WebViewImpl.prototype.setupAttributes = function() {
this.attributes[WebViewConstants.ATTRIBUTE_ALLOWSCALING] =
new WebViewAttributes.AllowScalingAttribute(this);
this.attributes[WebViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY] =
new WebViewAttributes.AllowTransparencyAttribute(this);
this.attributes[WebViewConstants.ATTRIBUTE_AUTOSIZE] =
new WebViewAttributes.AutosizeAttribute(this);
this.attributes[WebViewConstants.ATTRIBUTE_NAME] =
new WebViewAttributes.NameAttribute(this);
this.attributes[WebViewConstants.ATTRIBUTE_PARTITION] =
new WebViewAttributes.PartitionAttribute(this);
this.attributes[WebViewConstants.ATTRIBUTE_SRC] =
new WebViewAttributes.SrcAttribute(this);
var autosizeAttributes = [
WebViewConstants.ATTRIBUTE_MAXHEIGHT, WebViewConstants.ATTRIBUTE_MAXWIDTH,
WebViewConstants.ATTRIBUTE_MINHEIGHT, WebViewConstants.ATTRIBUTE_MINWIDTH
];
for (var attribute of autosizeAttributes) {
this.attributes[attribute] =
new WebViewAttributes.AutosizeDimensionAttribute(attribute, this);
}
// Forward proto.foo* method calls to WebViewImpl.foo*.
GuestViewContainer.forwardApiMethods(proto, apiMethods);
};
// Initiates navigation once the <webview> element is attached to the DOM.
......@@ -191,6 +197,14 @@ WebViewImpl.prototype.attachWindow$ = function(opt_guestInstanceId) {
return $Function.call(GuestViewContainer.prototype.attachWindow$, this);
};
WebViewImpl.prototype.addContentScripts = function(rules) {
return WebViewInternal.addContentScripts(this.viewInstanceId, rules);
};
WebViewImpl.prototype.removeContentScripts = function(names) {
return WebViewInternal.removeContentScripts(this.viewInstanceId, names);
};
// Shared implementation of executeScript() and insertCSS().
WebViewImpl.prototype.executeCode = function(func, args) {
if (!this.guest.getId()) {
......@@ -207,7 +221,87 @@ WebViewImpl.prototype.executeCode = function(func, args) {
$Array.slice(args));
$Function.apply(func, null, args);
return true;
}
};
WebViewImpl.prototype.executeScript = function(var_args) {
return this.executeCode(
WebViewInternal.executeScript, $Array.slice(arguments));
};
WebViewImpl.prototype.insertCSS = function(var_args) {
return this.executeCode(WebViewInternal.insertCSS, $Array.slice(arguments));
};
WebViewImpl.prototype.back = function(callback) {
return this.go(-1, callback);
};
WebViewImpl.prototype.canGoBack = function() {
return this.entryCount > 1 && this.currentEntryIndex > 0;
};
WebViewImpl.prototype.canGoForward = function() {
return this.currentEntryIndex >= 0 &&
this.currentEntryIndex < (this.entryCount - 1);
};
WebViewImpl.prototype.forward = function(callback) {
return this.go(1, callback);
};
WebViewImpl.prototype.getProcessId = function() {
return this.processId;
};
WebViewImpl.prototype.getUserAgent = function() {
return this.userAgentOverride || navigator.userAgent;
};
WebViewImpl.prototype.isUserAgentOverridden = function() {
return !!this.userAgentOverride &&
this.userAgentOverride != navigator.userAgent;
};
WebViewImpl.prototype.setUserAgentOverride = function(userAgentOverride) {
this.userAgentOverride = userAgentOverride;
if (!this.guest.getId()) {
// If we are not attached yet, then we will pick up the user agent on
// attachment.
return false;
}
WebViewInternal.overrideUserAgent(this.guest.getId(), userAgentOverride);
return true;
};
WebViewImpl.prototype.loadDataWithBaseUrl = function(
dataUrl, baseUrl, virtualUrl) {
if (!this.guest.getId()) {
return;
}
WebViewInternal.loadDataWithBaseUrl(
this.guest.getId(), dataUrl, baseUrl, virtualUrl, function() {
// Report any errors.
if (chrome.runtime.lastError != undefined) {
window.console.error(
'Error while running webview.loadDataWithBaseUrl: ' +
chrome.runtime.lastError.message);
}
});
};
WebViewImpl.prototype.print = function() {
return this.executeScript({code: 'window.print();'});
};
WebViewImpl.prototype.setZoom = function(zoomFactor, callback) {
if (!this.guest.getId()) {
this.cachedZoomFactor = zoomFactor;
return false;
}
this.cachedZoomFactor = 1;
WebViewInternal.setZoom(this.guest.getId(), zoomFactor, callback);
return true;
};
// Requests the <webview> element wihtin the embedder to enter fullscreen.
WebViewImpl.prototype.makeElementFullscreen = function() {
......@@ -219,6 +313,27 @@ WebViewImpl.prototype.makeElementFullscreen = function() {
// Implemented when the ChromeWebView API is available.
WebViewImpl.prototype.maybeSetupContextMenus = function() {};
(() => {
// For <webview> API methods which aren't explicitly defined on |WebViewImpl|,
// create default implementations which forward the call to |WebViewInternal|.
var createDefaultApiMethod = function(m) {
return function(var_args) {
if (!this.guest.getId()) {
return false;
}
var args = $Array.concat([this.guest.getId()], $Array.slice(arguments));
$Function.apply(WebViewInternal[m], null, args);
return true;
};
};
for (var methodName of WEB_VIEW_API_METHODS) {
if (WebViewImpl.prototype[methodName] == undefined) {
WebViewImpl.prototype[methodName] = createDefaultApiMethod(methodName);
}
}
})();
GuestViewContainer.registerElement(WebViewImpl);
// Exports.
......
......@@ -2,30 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// This module implements the public-facing API functions for the <webview> tag.
var WebViewInternal = getInternalApi ?
getInternalApi('webViewInternal') :
require('webViewInternal').WebViewInternal;
var WebViewImpl = require('webView').WebViewImpl;
// An array of <webview>'s public-facing API methods. Methods without custom
// implementations will be given default implementations that call into the
// internal API method with the same name in |WebViewInternal|. For example, a
// method called 'someApiMethod' would be given the following default
// implementation:
//
// WebViewImpl.prototype.someApiMethod = function(var_args) {
// if (!this.guest.getId()) {
// return false;
// }
// var args = $Array.concat([this.guest.getId()], $Array.slice(arguments));
// $Function.apply(WebViewInternal.someApiMethod, null, args);
// return true;
// };
//
// These default implementations come from createDefaultApiMethod() in
// web_view.js.
// This module contains the public-facing API functions for the <webview> tag.
var WEB_VIEW_API_METHODS = [
// Add content scripts for the guest page.
'addContentScripts',
......@@ -120,99 +98,5 @@ var WEB_VIEW_API_METHODS = [
'terminate'
];
// -----------------------------------------------------------------------------
// Custom API method implementations.
WebViewImpl.prototype.addContentScripts = function(rules) {
return WebViewInternal.addContentScripts(this.viewInstanceId, rules);
};
WebViewImpl.prototype.back = function(callback) {
return this.go(-1, callback);
};
WebViewImpl.prototype.canGoBack = function() {
return this.entryCount > 1 && this.currentEntryIndex > 0;
};
WebViewImpl.prototype.canGoForward = function() {
return this.currentEntryIndex >= 0 &&
this.currentEntryIndex < (this.entryCount - 1);
};
WebViewImpl.prototype.executeScript = function(var_args) {
return this.executeCode(WebViewInternal.executeScript,
$Array.slice(arguments));
};
WebViewImpl.prototype.forward = function(callback) {
return this.go(1, callback);
};
WebViewImpl.prototype.getProcessId = function() {
return this.processId;
};
WebViewImpl.prototype.getUserAgent = function() {
return this.userAgentOverride || navigator.userAgent;
};
WebViewImpl.prototype.insertCSS = function(var_args) {
return this.executeCode(WebViewInternal.insertCSS, $Array.slice(arguments));
};
WebViewImpl.prototype.isUserAgentOverridden = function() {
return !!this.userAgentOverride &&
this.userAgentOverride != navigator.userAgent;
};
WebViewImpl.prototype.loadDataWithBaseUrl = function(
dataUrl, baseUrl, virtualUrl) {
if (!this.guest.getId()) {
return;
}
WebViewInternal.loadDataWithBaseUrl(
this.guest.getId(), dataUrl, baseUrl, virtualUrl, function() {
// Report any errors.
if (chrome.runtime.lastError != undefined) {
window.console.error(
'Error while running webview.loadDataWithBaseUrl: ' +
chrome.runtime.lastError.message);
}
});
};
WebViewImpl.prototype.print = function() {
return this.executeScript({code: 'window.print();'});
};
WebViewImpl.prototype.removeContentScripts = function(names) {
return WebViewInternal.removeContentScripts(this.viewInstanceId, names);
};
WebViewImpl.prototype.setUserAgentOverride = function(userAgentOverride) {
this.userAgentOverride = userAgentOverride;
if (!this.guest.getId()) {
// If we are not attached yet, then we will pick up the user agent on
// attachment.
return false;
}
WebViewInternal.overrideUserAgent(this.guest.getId(), userAgentOverride);
return true;
};
WebViewImpl.prototype.setZoom = function(zoomFactor, callback) {
if (!this.guest.getId()) {
this.cachedZoomFactor = zoomFactor;
return false;
}
this.cachedZoomFactor = 1;
WebViewInternal.setZoom(this.guest.getId(), zoomFactor, callback);
return true;
};
// -----------------------------------------------------------------------------
WebViewImpl.getApiMethods = function() {
return WEB_VIEW_API_METHODS;
};
// Exports.
exports.$set('WEB_VIEW_API_METHODS', WEB_VIEW_API_METHODS);
......@@ -6,7 +6,6 @@
var GuestViewAttributes = require('guestViewAttributes').GuestViewAttributes;
var WebViewConstants = require('webViewConstants').WebViewConstants;
var WebViewImpl = require('webView').WebViewImpl;
var WebViewInternal = getInternalApi ?
getInternalApi('webViewInternal') :
require('webViewInternal').WebViewInternal;
......@@ -258,29 +257,15 @@ SrcAttribute.prototype.parse = function() {
WebViewInternal.navigate(this.view.guest.getId(), this.getValue());
};
// -----------------------------------------------------------------------------
// Sets up all of the webview attributes.
WebViewImpl.prototype.setupAttributes = function() {
this.attributes[WebViewConstants.ATTRIBUTE_ALLOWSCALING] =
new AllowScalingAttribute(this);
this.attributes[WebViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY] =
new AllowTransparencyAttribute(this);
this.attributes[WebViewConstants.ATTRIBUTE_AUTOSIZE] =
new AutosizeAttribute(this);
this.attributes[WebViewConstants.ATTRIBUTE_NAME] =
new NameAttribute(this);
this.attributes[WebViewConstants.ATTRIBUTE_PARTITION] =
new PartitionAttribute(this);
this.attributes[WebViewConstants.ATTRIBUTE_SRC] =
new SrcAttribute(this);
var autosizeAttributes = [WebViewConstants.ATTRIBUTE_MAXHEIGHT,
WebViewConstants.ATTRIBUTE_MAXWIDTH,
WebViewConstants.ATTRIBUTE_MINHEIGHT,
WebViewConstants.ATTRIBUTE_MINWIDTH];
for (var i = 0; autosizeAttributes[i]; ++i) {
this.attributes[autosizeAttributes[i]] =
new AutosizeDimensionAttribute(autosizeAttributes[i], this);
}
var WebViewAttributes = {
AllowScalingAttribute: AllowScalingAttribute,
AllowTransparencyAttribute: AllowTransparencyAttribute,
AutosizeDimensionAttribute: AutosizeDimensionAttribute,
AutosizeAttribute: AutosizeAttribute,
NameAttribute: NameAttribute,
PartitionAttribute: PartitionAttribute,
SrcAttribute: SrcAttribute
};
// Exports.
exports.$set('WebViewAttributes', WebViewAttributes);
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