Reviewers: metaweta,
Description:
Right now, caja.js does
load taming frame
when taming frame ready
load guest frame
when guest frame ready
run gadget
This is unnecessarily serial. Since we always need at least one guest
frame, we can start loading one before the taming frame is ready.
This change wraps guest frame creation in a frameMaker object that
can preload a frame and supply it to a later call to frameMaker.make().
Please review this at http://codereview.appspot.com/5486057/
Affected files:
M src/com/google/caja/plugin/caja.js
M src/com/google/caja/plugin/es53-frame-group.js
M src/com/google/caja/plugin/ses-frame-group.js
Index: src/com/google/caja/plugin/caja.js
===================================================================
--- src/com/google/caja/plugin/caja.js (revision 4679)
+++ src/com/google/caja/plugin/caja.js (working copy)
@@ -257,18 +257,21 @@
//----------------
function initES53(config, frameGroupReady) {
- // TODO(felix8a): start loading a guest-frame here too
// TODO(felix8a): with api change, can start cajoler early too
- loadCajaFrame(config, 'es53-taming-frame', function (frameWin) {
- var fg = frameWin.ES53FrameGroup(cajaInt, config, frameWin, window);
+ var guestMaker = makeFrameMaker(config, 'es53-guest-frame');
+ loadCajaFrame(config, 'es53-taming-frame', function (tamingWin) {
+ var fg = tamingWin.ES53FrameGroup(
+ cajaInt, config, tamingWin, window, guestMaker);
frameGroupReady(fg);
});
}
function trySES(config, frameGroupReady) {
- loadCajaFrame(config, 'ses-taming-frame', function (frameWin) {
- if (canSES(frameWin.ses, config.forceES5Mode)) {
- var fg = frameWin.SESFrameGroup(cajaInt, config, frameWin, window);
+ var guestMaker = makeFrameMaker(config, 'ses-guest-frame');
+ loadCajaFrame(config, 'ses-taming-frame', function (tamingWin) {
+ if (canSES(tamingWin.ses, config.forceES5Mode)) {
+ var fg = tamingWin.SESFrameGroup(
+ cajaInt, config, tamingWin, window, guestMaker);
frameGroupReady(fg);
} else {
config.log('Unable to use SES. Switching to ES53.');
@@ -291,6 +294,51 @@
//----------------
+ /**
+ * Returns an object that wraps loadCajaFrame() with preload support.
+ * Calling frameMaker.prefetch() will start creation of a new frame now,
+ * and make it available to a later call to frameMaker.make().
+ */
+ function makeFrameMaker(config, filename) {
+ var IDLE = 'IDLE', LOADING = 'LOADING', WAITING = 'WAITING';
+ var preState = IDLE, preWin, preReady;
+ var self = {
+ preload: function () {
+ if (preState === IDLE) {
+ preState = LOADING;
+ preWin = null;
+ loadCajaFrame(config, filename, function (win) {
+ preWin = win;
+ consumeIfReady();
+ });
+ }
+ },
+ make: function (onReady) {
+ if (preState === LOADING) {
+ preState = WAITING;
+ preReady = onReady;
+ consumeIfReady();
+ } else {
+ loadCajaFrame(config, filename, onReady);
+ }
+ }
+ };
+ self.preload();
+ return self;
+
+ function consumeIfReady() {
+ if (preState === WAITING && preWin) {
+ var win = preWin, ready = preReady;
+ preState = IDLE;
+ preWin = null;
+ preReady = null;
+ ready(win);
+ }
+ }
+ }
+
+ //----------------
+
function loadCajaFrame(config, filename, frameReady) {
var frameWin = createFrame(filename);
var url = joinUrl(
@@ -392,8 +440,6 @@
//----------------
- // TODO(felix8a): move getId etc into taming frame?
-
/**
* Enforces {@code typeof specimen === typename}, in which case
* specimen is returned.
Index: src/com/google/caja/plugin/es53-frame-group.js
===================================================================
--- src/com/google/caja/plugin/es53-frame-group.js (revision 4679)
+++ src/com/google/caja/plugin/es53-frame-group.js (working copy)
@@ -25,7 +25,7 @@
* @requires window
*/
-function ES53FrameGroup(cajaInt, config, tamingWin, feralWin) {
+function ES53FrameGroup(cajaInt, config, tamingWin, feralWin, guestMaker) {
if (tamingWin !== window) {
throw new Error('wrong frame');
}
@@ -60,7 +60,7 @@
function makeES5Frame(div, uriPolicy, es5ready, opt_idClass) {
var divs = cajaInt.prepareContainerDiv(div, feralWin, opt_idClass);
- cajaInt.loadCajaFrame(config, 'es53-guest-frame', function (guestWin) {
+ guestMaker.make(function (guestWin) {
var domicile = makeDomicile(divs, uriPolicy, guestWin);
var gman = GuestManager(divs, domicile, guestWin, es53run);
gman._loader = guestWin.loadModuleMaker(
Index: src/com/google/caja/plugin/ses-frame-group.js
===================================================================
--- src/com/google/caja/plugin/ses-frame-group.js (revision 4679)
+++ src/com/google/caja/plugin/ses-frame-group.js (working copy)
@@ -21,7 +21,7 @@
* @requires window
*/
-function SESFrameGroup(cajaInt, config, tamingWin, feralWin) {
+function SESFrameGroup(cajaInt, config, tamingWin, feralWin, guestMaker) {
if (tamingWin !== window) {
throw new Error('wrong frame');
}
@@ -54,7 +54,7 @@
function makeES5Frame(div, uriPolicy, es5ready, opt_idClass) {
var divs = cajaInt.prepareContainerDiv(div, feralWin, opt_idClass);
- cajaInt.loadCajaFrame(config, 'ses-guest-frame', function (guestWin) {
+ guestMaker.make(function (guestWin) {
var domicile = makeDomicile(divs, uriPolicy, guestWin);
var gman = GuestManager(divs, domicile, guestWin, sesRun);
es5ready(gman);