Add loop protection on keyup update

This commit is contained in:
Berkeley Martinez
2015-12-02 14:56:06 -08:00
parent a6a32d94cd
commit 096fba0de7
3 changed files with 35 additions and 10 deletions

View File

@ -1,7 +1,12 @@
$(document).ready(function() {
const common = window.common;
const { Observable } = window.Rx;
const { challengeName, challengeType, challengeTypes } = common;
const {
addLoopProtect,
challengeName,
challengeType,
challengeTypes
} = common;
common.init.forEach(function(init) {
init($);
@ -29,7 +34,13 @@ $(document).ready(function() {
.filter(() => common.challengeType === challengeTypes.HTML)
.flatMap(code => {
return common.detectUnsafeCode$(code)
.map(() => {
const combinedCode = common.head + code + common.tail;
return addLoopProtect(combinedCode);
})
.flatMap(code => common.updatePreview$(code))
.flatMap(() => common.checkPreview$({ code }))
.catch(err => Observable.just({ err }));
})
.subscribe(

View File

@ -12,6 +12,11 @@ window.common = (function(global) {
window.$ = parent.$.proxy(parent.$.fn.find, parent.$(document));
window.loopProtect = parent.loopProtect;
window.__err = null;
window.loopProtect.hit = function(line) {
window.__err = new Error(
'Potential infinite loop at line ' + line
);
};
</script>
<link
rel='stylesheet'
@ -39,9 +44,13 @@ window.common = (function(global) {
// and prime it with false
common.previewReady$ = new BehaviorSubject(false);
// runPreviewTests$ should be set up in the preview window
// These should be set up in the preview window
// if this error is seen it is because the function tried to run
// before the iframe has completely loaded
common.runPreviewTests$ =
() => Observable.throw(new Error('run preview not enabled'));
common.checkPreview$ =
() => Observable.throw(new Error('Preview not fully loaded'));
common.updatePreview$ = function updatePreview$(code = '') {
const preview = common.getIframe('preview');

View File

@ -10,12 +10,6 @@ window.$(document).ready(function() {
var tests = parent.tests;
var common = parent.common;
window.loopProtect.hit = function(line) {
window.__err = new Error(
'Potential infinite loop at line ' + line
);
};
common.getJsOutput = function evalJs(code = '') {
let output;
try {
@ -40,11 +34,13 @@ window.$(document).ready(function() {
return Rx.Observable.throw(window.__err);
}
// Iterate throught the test one at a time
// on new stacks
return Rx.Observable.from(tests, null, null, Rx.Scheduler.default)
// add delay here for firefox to catch up
.delay(100)
.map(test => {
const userTest = {};
common.appendToOutputDisplay('');
try {
/* eslint-disable no-eval */
eval(test);
@ -65,10 +61,19 @@ window.$(document).ready(function() {
}
return userTest;
})
// gather tests back into an array
.toArray()
.map(tests => ({ ...rest, tests, originalCode }));
};
// used when updating preview without running tests
common.checkPreview$ = function checkPreview$(args) {
if (window.__err) {
return Rx.Observable.throw(window.__err);
}
return Rx.Observable.just(args);
};
// now that the runPreviewTest$ is defined
// we set the subject to true
// this will let the updatePreview