Skip to content

Commit

Permalink
Initial preview rendering
Browse files Browse the repository at this point in the history
  • Loading branch information
Berkeley Martinez authored and Berkeley Martinez committed Jul 29, 2016
1 parent 1db5caa commit 9b7bd2a
Show file tree
Hide file tree
Showing 24 changed files with 473 additions and 157 deletions.
1 change: 1 addition & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
}
},
"env": {
"es6": true,
"browser": true,
"mocha": true,
"node": true
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public/js/main*
public/js/commonFramework*
public/js/sandbox*
public/js/iFrameScripts*
public/js/frame-runner*
public/js/plugin*
public/js/vendor*
public/js/faux*
Expand Down
70 changes: 70 additions & 0 deletions client/frame-runner.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
document.addEventListener('DOMContentLoaded', function() {
var common = parent.__common;
var Rx = parent.Rx;

common.getJsOutput = function evalJs(source = '') {
if (window.__err || !common.shouldRun()) {
return window.__err || 'source disabled';
}
let output;
try {
/* eslint-disable no-eval */
output = eval(source);
/* eslint-enable no-eval */
} catch (e) {
window.__err = e;
}
return output;
};

common.runTests$ = function runTests$({ tests = [], source }) {
const editor = { getValue() { return source; } };
if (window.__err) {
return Rx.Observable.throw(window.__err);
}

// Iterate through 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(({ text, testString }) => {
const newTest = { text, testString };
let test;
try {
/* eslint-disable no-eval */
test = eval(testString);
/* eslint-enable no-eval */
if (typeof test === 'function') {
// maybe sync/promise/observable
if (test.length === 0) {
test();
}
// callback test
if (test.length === 1) {
console.log('callback test');
}
}
} catch (e) {
newTest.err = e.message.split(':').shift();
}
return newTest;
})
// gather tests back into an array
.toArray();
};

// 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
// script now that we are ready.
common.testFrameReady$.onNext(true);
});
93 changes: 39 additions & 54 deletions client/iFrameScripts.js
Original file line number Diff line number Diff line change
@@ -1,73 +1,58 @@
/* eslint-disable no-undef, no-unused-vars, no-native-reassign */
// the $ on the iframe window object is the same
// as the one used on the main site, but
// uses the iframe document as the context
window.$(document).ready(function() {
var _ = parent._;
document.addEventListener('DOMContentLoaded', function() {
var common = parent.__common;
var Rx = parent.Rx;
var chai = parent.chai;
var assert = chai.assert;
var tests = parent.tests;
var common = parent.common;

common.getJsOutput = function evalJs(code = '') {
common.getJsOutput = function evalJs(source = '') {
if (window.__err || !common.shouldRun()) {
return window.__err || 'code disabled';
return window.__err || 'source disabled';
}
let output;
try {
/* eslint-disable no-eval */
output = eval(code);
output = eval(source);
/* eslint-enable no-eval */
} catch (e) {
window.__err = e;
}
return output;
};

common.runPreviewTests$ =
function runPreviewTests$({
tests = [],
originalCode,
...rest
}) {
const code = originalCode;
const editor = { getValue() { return originalCode; } };
if (window.__err) {
return Rx.Observable.throw(window.__err);
}
common.runTests$ = function runTests$({ tests = [], source }) {
const editor = { getValue() { return source; } };
if (window.__err) {
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 = {};
try {
/* eslint-disable no-eval */
eval(test);
/* eslint-enable no-eval */
} catch (e) {
userTest.err = e.message.split(':').shift();
} finally {
if (!test.match(/message: /g)) {
// assumes test does not contain arrays
// This is a patch until all test fall into this pattern
userTest.text = test
.split(',')
.pop();
userTest.text = 'message: ' + userTest.text + '\');';
} else {
userTest.text = test;
// Iterate through 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(({ text, testString }) => {
const newTest = { text, testString };
let test;
try {
/* eslint-disable no-eval */
test = eval(testString);
/* eslint-enable no-eval */
if (typeof test === 'function') {
// maybe sync/promise/observable
if (test.length === 0) {
test();
}
// callback test
if (test.length === 1) {
console.log('callback test');
}
}
return userTest;
})
// gather tests back into an array
.toArray()
.map(tests => ({ ...rest, tests, originalCode }));
};
} catch (e) {
newTest.err = e.message.split(':').shift();
}
return newTest;
})
// gather tests back into an array
.toArray();
};

// used when updating preview without running tests
common.checkPreview$ = function checkPreview$(args) {
Expand All @@ -81,5 +66,5 @@ window.$(document).ready(function() {
// we set the subject to true
// this will let the updatePreview
// script now that we are ready.
common.previewReady$.onNext(true);
common.testFrameReady$.onNext(true);
});
2 changes: 1 addition & 1 deletion client/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ createApp({
serviceOptions,
initialState,
middlewares: [ routingMiddleware ],
sagas,
sagas: [...sagas ],
sagaOptions,
reducers: { routing },
enhancers: [ devTools ]
Expand Down
21 changes: 0 additions & 21 deletions client/new-framework/add-loop-protect.js

This file was deleted.

13 changes: 0 additions & 13 deletions client/new-framework/execute-challenge-saga.js

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { helpers, Observable } from 'rx';

const throwForJsHtml = {
extname: /js|html/,
ext: /js|html/,
throwers: [
{
name: 'multiline-comment',
description: 'Detect if a JS multi-line comment is left open',
thrower: function checkForComments({ content }) {
const openingComments = content.match(/\/\*/gi);
const closingComments = content.match(/\*\//gi);
thrower: function checkForComments({ contents }) {
const openingComments = contents.match(/\/\*/gi);
const closingComments = contents.match(/\*\//gi);
if (
openingComments &&
(!closingComments || openingComments.length > closingComments.length)
Expand All @@ -20,19 +20,19 @@ const throwForJsHtml = {
name: 'nested-jQuery',
description: 'Nested dollar sign calls breaks browsers',
detectUnsafeJQ: /\$\s*?\(\s*?\$\s*?\)/gi,
thrower: function checkForNestedJquery({ content }) {
if (content.match(this.detectUnsafeJQ)) {
thrower: function checkForNestedJquery({ contents }) {
if (contents.match(this.detectUnsafeJQ)) {
throw new Error('Unsafe $($)');
}
}
}, {
name: 'unfinished-function',
description: 'lonely function keywords breaks browsers',
detectFunctionCall: /function\s*?\(|function\s+\w+\s*?\(/gi,
thower: function checkForUnfinishedFunction({ content: code }) {
thrower: function checkForUnfinishedFunction({ contents }) {
if (
code.match(/function/g) &&
!code.match(this.detectFunctionCall)
contents.match(/function/g) &&
!contents.match(this.detectFunctionCall)
) {
throw new Error(
'SyntaxError: Unsafe or unfinished function declaration'
Expand All @@ -43,26 +43,26 @@ const throwForJsHtml = {
name: 'unsafe console call',
description: 'console call stops tests scripts from running',
detectUnsafeConsoleCall: /if\s\(null\)\sconsole\.log\(1\);/gi,
thrower: function checkForUnsafeConsole({ content }) {
if (content.match(this.detectUnsafeConsoleCall)) {
thrower: function checkForUnsafeConsole({ contents }) {
if (contents.match(this.detectUnsafeConsoleCall)) {
throw new Error('Invalid if (null) console.log(1); detected');
}
}
}
]
};

export default function pretester() {
export default function throwers() {
const source = this;
return source.map(file$ => file$.flatMap(file => {
if (!throwForJsHtml.extname.test(file.extname)) {
if (!throwForJsHtml.ext.test(file.ext)) {
return Observable.just(file);
}
return Observable.from(throwForJsHtml.throwers)
.flatMap(({ thrower }) => {
.flatMap(context => {
try {
let finalObs;
const maybeObservableOrPromise = thrower(file);
const maybeObservableOrPromise = context.thrower(file);
if (helpers.isPromise(maybeObservableOrPromise)) {
finalObs = Observable.fromPromise(maybeObservableOrPromise);
} else if (Observable.isObservable(maybeObservableOrPromise)) {
Expand Down
37 changes: 37 additions & 0 deletions client/new-framework/transformers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Observable } from 'rx';
import loopProtect from 'loop-protect';

loopProtect.hit = function hit(line) {
var err = 'Error: Exiting potential infinite loop at line ' +
line +
'. To disable loop protection, write: \n\\/\\/ noprotect\nas the first' +
'line. Beware that if you do have an infinite loop in your code' +
'this will crash your browser.';
console.error(err);
};

const transformersForHtmlJS = {
ext: /html|js/,
transformers: [
{
name: 'add-loop-protect',
transformer: function addLoopProtect(file) {
file.contents = loopProtect(file.contents);
return file;
}
}
]
};


// Observable[Observable[File]]::addLoopProtect() => Observable[String]
export default function transformers() {
const source = this;
return source.map(files$ => files$.flatMap(file => {
if (!transformersForHtmlJS.ext.test(file.ext)) {
return Observable.just(file);
}
return Observable.from(transformersForHtmlJS.transformers)
.reduce((file, context) => context.transformer(file), file);
}));
}
Loading

0 comments on commit 9b7bd2a

Please sign in to comment.