blob: f28bf6d17c18d12b4e12eba1dbdc169dd6c7fdd2 [file] [log] [blame]
// 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.
// This module implements the ExtensionView <extensionview>.
var GuestViewContainer = require('guestViewContainer').GuestViewContainer;
var ExtensionViewConstants =
require('extensionViewConstants').ExtensionViewConstants;
var ExtensionViewEvents = require('extensionViewEvents').ExtensionViewEvents;
var ExtensionViewInternal =
require('extensionViewInternal').ExtensionViewInternal;
function ExtensionViewImpl(extensionviewElement) {
GuestViewContainer.call(this, extensionviewElement, 'extensionview');
// A queue of objects in the order they should be loaded.
// Every load call will add the given src, as well as the resolve and reject
// functions. Each src will be loaded in the order they were called.
this.loadQueue = [];
// The current src that is loading.
// @type {Object<!string, function, function>}
this.pendingLoad = null;
new ExtensionViewEvents(this, this.viewInstanceId);
}
ExtensionViewImpl.prototype.__proto__ = GuestViewContainer.prototype;
ExtensionViewImpl.VIEW_TYPE = 'ExtensionView';
ExtensionViewImpl.setupElement = function(proto) {
var apiMethods = ExtensionViewImpl.getApiMethods();
GuestViewContainer.forwardApiMethods(proto, apiMethods);
};
ExtensionViewImpl.prototype.createGuest = function(callback) {
this.guest.create(this.buildParams(), $Function.bind(function() {
this.attachWindow$();
callback();
}, this));
};
ExtensionViewImpl.prototype.buildContainerParams = function() {
var params = {};
for (var i in this.attributes) {
params[i] = this.attributes[i].getValue();
}
return params;
};
ExtensionViewImpl.prototype.onElementDetached = function() {
this.guest.destroy();
// Reset all attributes.
for (var i in this.attributes) {
this.attributes[i].setValueIgnoreMutation();
}
};
// Updates src upon loadcommit.
ExtensionViewImpl.prototype.onLoadCommit = function(url) {
this.attributes[ExtensionViewConstants.ATTRIBUTE_SRC].
setValueIgnoreMutation(url);
};
// Loads the next pending src from |loadQueue| to the extensionview.
ExtensionViewImpl.prototype.loadNextSrc = function() {
// If extensionview isn't currently loading a src, load the next src
// in |loadQueue|. Otherwise, do nothing.
if (!this.pendingLoad && this.loadQueue.length) {
this.pendingLoad = $Array.shift(this.loadQueue);
var src = this.pendingLoad.src;
var resolve = this.pendingLoad.resolve;
var reject = this.pendingLoad.reject;
// The extensionview validates the |src| twice, once in |parseSrc| and then
// in |loadSrc|. The |src| isn't checked directly in |loadNextSrc| for
// validity since the sending renderer (WebUI) is trusted.
ExtensionViewInternal.parseSrc(
src, $Function.bind(function(isSrcValid, extensionId) {
// Check if the src is valid.
if (!isSrcValid) {
reject('Failed to load: src is not valid.');
return;
}
// Destroy the current guest and create a new one if extension ID
// is different.
//
// This may happen if the extensionview is loads an extension page, and
// is then intended to load a page served from a different extension in
// the same part of the WebUI.
//
// The two calls may look like the following:
// extensionview.load('chrome-extension://firstId/page.html');
// extensionview.load('chrome-extension://secondId/page.html');
// The second time load is called, we destroy the current guest since
// we will be loading content from a different extension.
if (extensionId !=
this.attributes[ExtensionViewConstants.ATTRIBUTE_EXTENSION]
.getValue()) {
this.guest.destroy();
// Update the extension and src attributes.
this.attributes[ExtensionViewConstants.ATTRIBUTE_EXTENSION]
.setValueIgnoreMutation(extensionId);
this.attributes[ExtensionViewConstants.ATTRIBUTE_SRC]
.setValueIgnoreMutation(src);
this.createGuest($Function.bind(function() {
if (this.guest.getId() <= 0) {
reject('Failed to load: guest creation failed.');
} else {
resolve('Successful load.');
}
}, this));
} else {
ExtensionViewInternal.loadSrc(this.guest.getId(), src,
$Function.bind(function(hasLoadSucceeded) {
if (!hasLoadSucceeded) {
reject('Failed to load.');
} else {
// Update the src attribute.
this.attributes[ExtensionViewConstants.ATTRIBUTE_SRC]
.setValueIgnoreMutation(src);
resolve('Successful load.');
}
}, this));
}
}, this));
}
};
GuestViewContainer.registerElement(ExtensionViewImpl);
// Exports.
exports.$set('ExtensionViewImpl', ExtensionViewImpl);