");
- $('#testSuite').append(testDoc);
- testSuccess();
-};
-
-var postError = function(data) {
- var testDoc = document.createElement("div");
- $(testDoc)
- .html("
" + JSON.parse(data) + "
");
- $('#testSuite').append(testDoc);
-};
-var goodTests = 0;
-var testSuccess = function() {
- goodTests++;
- if (goodTests === tests.length) {
- showCompletion();
- }
-};
-
-function doLinting () {
- editor.operation(function () {
- for (var i = 0; i < widgets.length; ++i)
- editor.removeLineWidget(widgets[i]);
- widgets.length = 0;
- JSHINT(editor.getValue());
- for (var i = 0; i < JSHINT.errors.length; ++i) {
- var err = JSHINT.errors[i];
- if (!err) continue;
- var msg = document.createElement("div");
- var icon = msg.appendChild(document.createElement("span"));
- icon.innerHTML = "!!";
- icon.className = "lint-error-icon";
- msg.appendChild(document.createTextNode(err.reason));
- msg.className = "lint-error";
- widgets.push(editor.addLineWidget(err.line - 1, msg, {
- coverGutter: false,
- noHScroll: true
- }));
- }
- });
-};
-
-//$('#testSuite').empty();
-function showCompletion() {
- var time = Math.floor(Date.now()) - started;
- ga('send', 'event', 'Challenge', 'solved', challenge_Name + ', Time: ' + time);
- $('#next-courseware-button').removeAttr('disabled');
- $('#next-courseware-button').addClass('animated tada');
- if (!userLoggedIn) {
- $('#complete-courseware-dialog').modal('show');
- }
- $('body').keydown(function(e) {
- if (e.ctrlKey && e.keyCode == 13) {
- $('#next-courseware-button').click();
- $('#next-courseware-button').unbind('click');
- }
- });
-}
-
-/*
- Local Storage Update System By Andrew Cay(Resto)
- codeStorage: singleton object that contains properties and methods related to
- dealing with the localStorage system.
- The keys work off of the variable challenge_name to make unique identifiers per bonfire
-
- Two extra functionalities:
- Added anonymous version checking system incase of future updates to the system
- Added keyup listener to editor(myCodeMirror) so the last update has been saved to storage
- */
-var codeStorage = {
- version: 0.01,
- keyVersion:"saveVersion",
- keyValue: null,//where the value of the editor is saved
- updateWait: 2000,// 2 seconds
- updateTimeoutId: null,
- eventArray: []//for firing saves
-};
-// Returns true if the editor code was saved since last key press (use this if you want to make a "saved" notification somewhere")
-codeStorage.hasSaved = function(){
- return ( updateTimeoutId === null );
-};
-codeStorage.onSave = function(func){
- codeStorage.eventArray.push(func);
-};
-codeStorage.setSaveKey = function(key){
- codeStorage.keyValue = key + 'Val';
-};
-codeStorage.getEditorValue = function(){
- return ('' + localStorage.getItem(codeStorage.keyValue));
-};
-
-codeStorage.isAlive = function() {
- var val = this.getEditorValue()
- return val !== 'null' &&
- val !== 'undefined' &&
- (val && val.length > 0);
-};
-codeStorage.updateStorage = function(){
- if(typeof(Storage) !== undefined) {
- var value = editor.getValue();
- localStorage.setItem(codeStorage.keyValue, value);
- } else {
- var debugging = false;
- if( debugging ){
- console.log('no web storage');
- }
- }
- codeStorage.updateTimeoutId = null;
- codeStorage.eventArray.forEach(function(func){
- func();
- });
-};
-//Update Version
-(function(){
- var savedVersion = localStorage.getItem('saveVersion');
- if( savedVersion === null ){
- localStorage.setItem(codeStorage.keyVersion, codeStorage.version);//just write current version
- }else{
- if( savedVersion !== codeStorage.version ){
- //Update version
- }
- }
-})();
-
-
-
-///Set everything up one page
-/// Update local save when editor has changed
-codeStorage.setSaveKey(challenge_Name);
-editor.on('keyup', function(){
- window.clearTimeout(codeStorage.updateTimeoutId);
- codeStorage.updateTimeoutId = window.setTimeout(codeStorage.updateStorage, codeStorage.updateWait);
-});
-
-var editorValue;
-
-
-var challengeSeed = challengeSeed || null;
-var tests = tests || [];
-
-
-var allSeeds = '';
-(function() {
- challengeSeed.forEach(function(elem) {
- allSeeds += elem + '\n';
- });
-})();
-
-editorValue = (codeStorage.isAlive())? codeStorage.getEditorValue() : allSeeds;
-
-editor.setValue(editorValue.replace((/fccss/gi), ''));
-editor.refresh();
-
-var resetEditor = function resetEditor() {
- editor.setValue(allSeeds.replace((/fccss/gi), ''));
- updatePreview();
- codeStorage.updateStorage();
-};
-
-
-
-/*
-var challengeSeed = challengeSeed || null;
-var allSeeds = '';
-(function() {
- challengeSeed.forEach(function(elem) {
- allSeeds += elem.replace(/fccss/g, '') + '\n';
- });
- editor.setValue(allSeeds);
- (function() {
- setTimeout(function() {
- editor.refresh();
- }, 200);
- })();
-})();
-*/
diff --git a/public/js/lib/coursewares/coursewaresJSFramework_0.0.6.js b/public/js/lib/coursewares/coursewaresJSFramework_0.0.6.js
deleted file mode 100644
index ddeb9519f4..0000000000
--- a/public/js/lib/coursewares/coursewaresJSFramework_0.0.6.js
+++ /dev/null
@@ -1,394 +0,0 @@
-var widgets = [];
-var myCodeMirror = CodeMirror.fromTextArea(document.getElementById("codeEditor"), {
- lineNumbers: true,
- mode: "javascript",
- theme: 'monokai',
- runnable: true,
- lint: true,
- matchBrackets: true,
- autoCloseBrackets: true,
- scrollbarStyle: 'null',
- lineWrapping: true,
- gutters: ["CodeMirror-lint-markers"],
- onKeyEvent: doLinting
-});
-var editor = myCodeMirror;
-editor.setSize("100%", "auto");
-
-// Hijack tab key to enter two spaces intead
-editor.setOption("extraKeys", {
- Tab: function(cm) {
- if (cm.somethingSelected()) {
- cm.indentSelection("add");
- } else {
- var spaces = Array(cm.getOption("indentUnit") + 1).join(" ");
- cm.replaceSelection(spaces);
- }
- },
- "Shift-Tab": function(cm) {
- if (cm.somethingSelected()) {
- cm.indentSelection("subtract");
- } else {
- var spaces = Array(cm.getOption("indentUnit") + 1).join(" ");
- cm.replaceSelection(spaces);
- }
- },
- "Ctrl-Enter": function() {
- bonfireExecute();
- return false;
- }
-});
-
-
-var attempts = 0;
-if (attempts) {
- attempts = 0;
-}
-
-
-var codeOutput = CodeMirror.fromTextArea(document.getElementById("codeOutput"), {
- lineNumbers: false,
- mode: "text",
- theme: 'monokai',
- readOnly: 'nocursor',
- lineWrapping: true
-});
-
-codeOutput.setValue('/**\n' +
- ' * Your output will go here.\n' + ' * Console.log() -type statements\n' +
- ' * will appear in your browser\'s\n' + ' * DevTools JavaScript console.\n' +
- ' */');
-codeOutput.setSize("100%", "100%");
-var info = editor.getScrollInfo();
-var after = editor.charCoords({
- line: editor.getCursor().line + 1,
- ch: 0
-}, "local").top;
-if (info.top + info.clientHeight < after)
- editor.scrollTo(null, after - info.clientHeight + 3);
-
-function doLinting() {
- editor.operation(function() {
- for (var i = 0; i < widgets.length; ++i)
- editor.removeLineWidget(widgets[i]);
- widgets.length = 0;
- JSHINT(editor.getValue());
- for (var i = 0; i < JSHINT.errors.length; ++i) {
- var err = JSHINT.errors[i];
- if (!err) continue;
- var msg = document.createElement("div");
- var icon = msg.appendChild(document.createElement("span"));
- icon.innerHTML = "!!";
- icon.className = "lint-error-icon";
- msg.appendChild(document.createTextNode(err.reason));
- msg.className = "lint-error";
- widgets.push(editor.addLineWidget(err.line - 1, msg, {
- coverGutter: false,
- noHScroll: true
- }));
- }
- });
-}
-
-$('#submitButton').on('click', function() {
- bonfireExecute();
-});
-
-function bonfireExecute() {
- attempts++;
- ga('send', 'event', 'Challenge', 'ran-code', challenge_Name);
- userTests = null;
- $('#codeOutput').empty();
- var userJavaScript = myCodeMirror.getValue();
- var failedCommentTest = false;
- if(userJavaScript.match(/\/\*/gi) && userJavaScript.match(/\*\//gi) == null){
- failedCommentTest = true;
- }
- else if(!failedCommentTest && userJavaScript.match(/\/\*/gi) && userJavaScript.match(/\/\*/gi).length > userJavaScript.match(/\*\//gi).length){
- failedCommentTest = true;
- }
- userJavaScript = removeComments(userJavaScript);
- userJavaScript = scrapeTests(userJavaScript);
- // simple fix in case the user forgets to invoke their function
-
- submit(userJavaScript, function(cls, message) {
- if(failedCommentTest){
- myCodeMirror.setValue(myCodeMirror.getValue() + "*/");
- console.log('Caught Unfinished Comment');
- codeOutput.setValue("Unfinished mulit-line comment");
- failedCommentTest = false;
- }
- else if (cls) {
- codeOutput.setValue(message.error);
- runTests('Error', null);
- } else {
- codeOutput.setValue(message.output);
- codeOutput.setValue(codeOutput.getValue().replace(/\\\"/gi,''));
- message.input = removeLogs(message.input);
- runTests(null, message);
- }
- });
-}
-
-
-var userTests;
-var testSalt = Math.random();
-
-
-var scrapeTests = function(userJavaScript) {
-
- // insert tests from mongo
- for (var i = 0; i < tests.length; i++) {
- userJavaScript += '\n' + tests[i];
- }
-
- var counter = 0;
- var regex = new RegExp(
- /(expect(\s+)?\(.*\;)|(assert(\s+)?\(.*\;)|(assert\.\w.*\;)|(.*\.should\..*\;)/
- );
- var match = regex.exec(userJavaScript);
- while (match != null) {
- var replacement = '//' + counter + testSalt;
- userJavaScript = userJavaScript.substring(0, match.index) + replacement +
- userJavaScript.substring(match.index + match[0].length);
-
- if (!userTests) {
- userTests = [];
- }
- userTests.push({
- "text": match[0],
- "line": counter,
- "err": null
- });
- counter++;
- match = regex.exec(userJavaScript);
- }
-
- return userJavaScript;
-};
-
-function removeComments(userJavaScript) {
- var regex = new RegExp(/(\/\*[^(\*\/)]*\*\/)|\/\/[^\n]*/g);
- return userJavaScript.replace(regex, '');
-}
-
-function removeLogs(userJavaScript) {
- return userJavaScript.replace(/(console\.[\w]+\s*\(.*\;)/g, '');
-}
-
-var pushed = false;
-var createTestDisplay = function() {
- if (pushed) {
- userTests.pop();
- }
- for (var i = 0; i < userTests.length; i++) {
- var test = userTests[i];
- var testDoc = document.createElement("div");
- if (test.err != null) {
- console.log('Should be displaying bad tests');
- $(testDoc)
- .html(
- "
" +
- test.text + "
" +
- test.err + "
")
- .appendTo($('#testSuite'));
- } else {
- $(testDoc)
- .html(
- "
")
- .appendTo($('#testSuite'));
- }
- };
-};
-
-var expect = chai.expect;
-var assert = chai.assert;
-var should = chai.should();
-
-
-var reassembleTest = function(test, data) {
- var lineNum = test.line;
- var regexp = new RegExp("\/\/" + lineNum + testSalt);
- return data.input.replace(regexp, test.text);
-};
-
-var runTests = function(err, data) {
- var allTestsPassed = true;
- pushed = false;
- $('#testSuite').children().remove();
- if (err && userTests.length > 0) {
- userTests = [{
- text: "Program Execution Failure",
- err: "No user tests were run."
- }];
- createTestDisplay();
- }
- //Add blocks to test exploits here!
- else if(editorValue.match(/if\s\(null\)\sconsole\.log\(1\);/gi)){
- allTestsPassed = false;
- userTests = [{
- text: "Program Execution Failure",
- err: "Invalid if (null) console.log(1); detected"
- }];
- createTestDisplay();
- }
- else if (userTests) {
- userTests.push(false);
- pushed = true;
- userTests.forEach(function(chaiTestFromJSON, indexOfTestArray,
- __testArray) {
- try {
- if (chaiTestFromJSON) {
- var output = eval(reassembleTest(chaiTestFromJSON, data));
- }
- } catch (error) {
- allTestsPassed = false;
- __testArray[indexOfTestArray].err = error.message;
- } finally {
- if (!chaiTestFromJSON) {
- createTestDisplay();
- }
- }
- });
-
- if (allTestsPassed) {
- allTestsPassed = false;
- showCompletion();
- }
-
- }
-};
-
-function showCompletion() {
- var time = Math.floor(Date.now()) - started;
- ga('send', 'event', 'Challenge', 'solved', challenge_Name + ', Time: ' + time +
- ', Attempts: ' + attempts);
- var bonfireSolution = myCodeMirror.getValue();
- var didCompleteWith = $('#completed-with').val() || null;
- $.post(
- '/completed-bonfire/', {
- challengeInfo: {
- challengeId: challenge_Id,
- challengeName: challenge_Name,
- completedWith: didCompleteWith,
- challengeType: challengeType,
- solution: bonfireSolution
- }
- },
- function(res) {
- if (res) {
- $('#complete-courseware-dialog').modal('show');
- $('#complete-courseware-dialog').keydown(function(e) {
- if (e.ctrlKey && e.keyCode == 13) {
- $('#next-courseware-button').click();
- }
- });
- }
- }
- );
-
-}
-
-
-/*
- Local Storage Update System By Andrew Cay(Resto)
- codeStorage: singleton object that contains properties and methods related to
- dealing with the localStorage system.
- The keys work off of the variable challenge_name to make unique identifiers per bonfire
-
- Two extra functionalities:
- Added anonymous version checking system incase of future updates to the system
- Added keyup listener to editor(myCodeMirror) so the last update has been saved to storage
- */
-var codeStorage = {
- version: 0.01,
- keyVersion:"saveVersion",
- keyValue: null,//where the value of the editor is saved
- updateWait: 2000,// 2 seconds
- updateTimeoutId: null,
- eventArray: []//for firing saves
-};
-// Returns true if the editor code was saved since last key press (use this if you want to make a "saved" notification somewhere")
-codeStorage.hasSaved = function(){
- return ( updateTimeoutId === null );
-};
-codeStorage.onSave = function(func){
- codeStorage.eventArray.push(func);
-};
-codeStorage.setSaveKey = function(key){
- codeStorage.keyValue = key + 'Val';
-};
-codeStorage.getEditorValue = function(){
- return ('' + localStorage.getItem(codeStorage.keyValue));
-};
-
-codeStorage.isAlive = function() {
- var val = this.getEditorValue()
- return val !== 'null' &&
- val !== 'undefined' &&
- (val && val.length > 0);
-}
-codeStorage.updateStorage = function(){
- if(typeof(Storage) !== undefined) {
- var value = editor.getValue();
- localStorage.setItem(codeStorage.keyValue, value);
- } else {
- var debugging = false;
- if( debugging ){
- console.log('no web storage');
- }
- }
- codeStorage.updateTimeoutId = null;
- codeStorage.eventArray.forEach(function(func){
- func();
- });
-};
-//Update Version
-(function(){
- var savedVersion = localStorage.getItem('saveVersion');
- if( savedVersion === null ){
- localStorage.setItem(codeStorage.keyVersion, codeStorage.version);//just write current version
- }else{
- if( savedVersion !== codeStorage.version ){
- //Update version
- }
- }
-})();
-
-
-
-///Set everything up one page
-/// Update local save when editor has changed
-codeStorage.setSaveKey(challenge_Name);
-editor.on('keyup', function(){
- window.clearTimeout(codeStorage.updateTimeoutId);
- codeStorage.updateTimeoutId = window.setTimeout(codeStorage.updateStorage, codeStorage.updateWait);
-});
-
-var editorValue;
-
-
-var challengeSeed = challengeSeed || null;
-var tests = tests || [];
-
-
-var allSeeds = '';
-(function() {
- challengeSeed.forEach(function(elem) {
- allSeeds += elem + '\n';
- });
-})();
-
-editorValue = (codeStorage.isAlive())? codeStorage.getEditorValue() : allSeeds;
-
-myCodeMirror.setValue(editorValue);
-
-var resetEditor = function resetEditor() {
- editor.setValue(allSeeds);
- codeStorage.updateStorage();
-};
-
-$(document).ready(function(){
- bonfireExecute();
-});
diff --git a/public/js/lib/coursewares/sandbox.js b/public/js/lib/coursewares/sandbox.js
index 55c80ea99d..75452114eb 100644
--- a/public/js/lib/coursewares/sandbox.js
+++ b/public/js/lib/coursewares/sandbox.js
@@ -73,7 +73,9 @@ var reset = function() {
setTimeout( function() {
endLoading();
console.log("resetting on fatal plugin error");
- codeOutput.setValue("Sorry, your code is either too slow, has a fatal error, or contains an infinite loop.");
+ if(challengeType === 0){
+ codeOutput.setValue("Sorry, your code is either too slow, has a fatal error, or contains an infinite loop.");
+ }
reset();
}, 10);
});
diff --git a/server/views/coursewares/showBonfire.jade b/server/views/coursewares/showBonfire.jade
index 769311c29c..58a00b5f54 100644
--- a/server/views/coursewares/showBonfire.jade
+++ b/server/views/coursewares/showBonfire.jade
@@ -123,7 +123,9 @@ block content
form.code
.form-group.codeMirrorView
textarea#codeEditor(autofocus=true, style='display: none;')
- script(src='/js/lib/coursewares/coursewaresJSFramework_0.0.6.js')
+ script(src='/js/lib/coursewares/commonFrameWork.js')
+ script.
+ editor.setOption("mode", "javascript");
#complete-courseware-dialog.modal(tabindex='-1')
.modal-dialog.animated.zoomIn.fast-animation
diff --git a/server/views/coursewares/showHTML.jade b/server/views/coursewares/showHTML.jade
index 85970895f9..65659f2f9c 100644
--- a/server/views/coursewares/showHTML.jade
+++ b/server/views/coursewares/showHTML.jade
@@ -31,10 +31,11 @@ block content
for sentence in details
p.wrappable.negative-10!= sentence
.negative-bottom-margin-30
+ label.negative-10.btn.btn-primary.btn-block#submitButton
+ i.fa.fa-play
+ | Run code (ctrl + enter)
+ br
if (user)
- label.btn.btn-primary.btn-block.negative-10#next-courseware-button
- .ion-checkmark-circled
- | Go to my next challenge (ctrl + enter)
.button-spacer
.btn-group.input-group.btn-group-justified
label.btn.btn-success#trigger-reset-modal
@@ -71,6 +72,9 @@ block content
form.code
.codeMirrorView
textarea#codeEditor(autofocus=true, style='display: none;')
+ script(src = '/js/lib/coursewares/commonFrameWork.js')
+ script.
+ editor.setOption("mode", "text/html");
.col-md-4.col-lg-3
.hidden-xs.hidden-sm
img.iphone-position.iframe-scroll(src="https://s3.amazonaws.com/freecodecamp/iphone6-frame.png", style = "z-index: -2;")
@@ -86,6 +90,8 @@ block content
.text-center
.animated.zoomInDown.delay-half
span.completion-icon.ion-checkmark-circled.text-primary
- a.animated.fadeIn.btn.btn-lg.signup-btn.btn-block(href='/login') Sign in so you can save your progress
+ if(user)
+ a.animated.fadeIn.btn.btn-lg.btn-primary.btn-block(href='/challenges/next-challenge') Go to the next challenge
+ else
+ a.animated.fadeIn.btn.btn-lg.signup-btn.btn-block(href='/login') Sign in so you can save your progress
include ../partials/challenge-modals
- script(src="/js/lib/coursewares/coursewaresHCJQFramework_0.1.9.js")
diff --git a/server/views/coursewares/showJS.jade b/server/views/coursewares/showJS.jade
index 85ab33adaa..2d8acf85a3 100644
--- a/server/views/coursewares/showJS.jade
+++ b/server/views/coursewares/showJS.jade
@@ -72,7 +72,9 @@ block content
form.code
.codeMirrorView
textarea#codeEditor(autofocus=true, style='display: none;')
- script(src='/js/lib/coursewares/coursewaresJSFramework_0.0.6.js')
+ script(src = '/js/lib/coursewares/commonFrameWork.js')
+ script.
+ editor.setOption("mode", "javascript");
#complete-courseware-dialog.modal(tabindex='-1')
.modal-dialog.animated.zoomIn.fast-animation
.modal-content