Commit 5606fe76 by Sebastian Committed by Romain Courteaud

Allow renderjs from JS only, without initial gadget-tag/script-tag

The inital loaded HTML does not contain anything of renderjs and gets added only after pageload.
Instead of registering init() for the DOMContentLoaded event directly, a deferred promise is used which gets resolve either by the event, or by a manual call of rJS.manualBootstrap().

Tests:
* injects rsvp/renderjs in a blank iframe
* makes sure renderjs is only present after it was injected
* calls manual bootstrap to initialzed renderjs
* creates small test gadget to ensure renderjs is working within the iframe (after bootstrap was executed)
1 parent 38a9b387
......@@ -132,7 +132,8 @@
scope_increment = 0,
isAbsoluteOrDataURL = new RegExp('^(?:[a-z]+:)?//|data:', 'i'),
is_page_unloaded = false,
error_list = [];
error_list = [],
bootstrap_deferred_object = new RSVP.defer();
window.addEventListener('error', function (error) {
error_list.push(error);
......@@ -1322,6 +1323,16 @@
// Bootstrap process. Register the self gadget.
///////////////////////////////////////////////////
// Manually initializes the self gadget if the DOMContentLoaded event
// is triggered before everything was ready.
// (For instance, the HTML-tag for the self gadget gets inserted after
// page load)
renderJS.manualBootstrap = function () {
bootstrap_deferred_object.resolve();
};
function bootstrap() {
var url = removeHash(window.location.href),
TmpConstructor,
......@@ -1634,7 +1645,16 @@
throw e;
});
}
document.addEventListener('DOMContentLoaded', init, false);
document.addEventListener('DOMContentLoaded',
bootstrap_deferred_object.resolve, false);
// Return Promies/Queue here instead of directly calling init()
return new RSVP.Queue()
.push(function () {
return bootstrap_deferred_object.promise;
})
.push(function () {
return init();
});
});
loading_gadget_promise
......
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<script src="./inject_script.js"></script>
</head>
<body></body>
</html>
/*jslint nomen: true*/
// can't use RSVP here because its not loaded (neccessarily)
function inject_script(src, resolve) {
// inject RSVP
var script = document.createElement("script");
script.onload = function() {
resolve();
};
script.src = src;
document.head.appendChild(script);
}
......@@ -5768,6 +5768,79 @@
});
});
test('check manual bootstrap', function () {
var fixture = document.getElementById("qunit-fixture"),
iframe;
// The iframe for an isolated renderjs-free environment
// to test the manual inject
fixture.innerHTML = "<iframe id=renderjsIsolatedIframe " +
"src='./inject_script.html'></iframe>";
iframe = document.getElementById("renderjsIsolatedIframe");
stop();
return new RSVP.Promise(function (resolve, reject) {
iframe.addEventListener("load", function (e) {
resolve(e.target.result);
});
})
.then(function () {
ok(
!iframe.contentWindow.hasOwnProperty("renderJS"),
"RJS NOT available before inject"
);
return new RSVP.Promise(function (resolve, reject) {
iframe.contentWindow.inject_script(
"../node_modules/rsvp/dist/rsvp-2.0.4.js",
resolve
);
});
})
.then(function () {
return new RSVP.Promise(function (resolve, reject) {
iframe.contentWindow.inject_script(
"../dist/renderjs-latest.js",
resolve
);
});
})
.then(function () {
ok(
iframe.contentWindow.hasOwnProperty("renderJS"),
"RJS available after inject"
);
})
.then(function () {
// create parentGadget in iframe, then initialize RJS
var parentDiv = iframe.contentDocument.createElement("div");
parentDiv.setAttribute(
"data-gadget-url",
"./trigger_rjsready_event_on_ready_gadget.html"
);
iframe.contentDocument.body.appendChild(parentDiv);
return new RSVP.Promise(function (resolve, reject) {
// listen for an event fired in the ready function of the parent
// gadget
parentDiv.addEventListener("rjsready", function (e) {
resolve();
});
// if no event is fired within 500ms, just resolve and fail later
window.setTimeout(function () {
reject("Timeout, RenderJS is not Ready");
}, 500);
iframe.contentWindow.rJS.manualBootstrap();
});
})
.then(function () {
ok(true, "RJS correctly bootstrapped and parent is ready");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
}(document, renderJS, QUnit, sinon, URI, URL, Event,
MutationObserver));
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<title>Test Gadget</title>
<script src="../node_modules/rsvp/dist/rsvp-2.0.4.js"></script>
<script src="../dist/renderjs-latest.js"></script>
<script src="trigger_rjsready_event_on_ready_gadget.js" type="text/javascript"></script>
</head>
<body>
</body>
</html>
/*global window, rJS, jIO, FormData */
/*jslint indent: 2, maxerr: 3 */
(function (window, rJS) {
"use strict";
rJS(window)
.ready(function (gadget) {
return gadget.getElement()
.push(function (element) {
element.dispatchEvent(new Event("rjsready"));
});
});
}(window, rJS));
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!