diff options
Diffstat (limited to 'assets/javascript')
-rw-r--r-- | assets/javascript/app.js | 29 | ||||
-rw-r--r-- | assets/javascript/core/exercise.js | 45 | ||||
-rw-r--r-- | assets/javascript/utils/execute.js | 91 |
3 files changed, 141 insertions, 24 deletions
diff --git a/assets/javascript/app.js b/assets/javascript/app.js index c6197df..fde6e20 100644 --- a/assets/javascript/app.js +++ b/assets/javascript/app.js @@ -1,8 +1,9 @@ require([ "jQuery", "core/state", - "core/progress" -], function($, _state, progress){ + "core/exercise", + "core/progress", +], function($, _state, exercise, progress){ $(document).ready(function() { var state = _state(); var $book = state.$book; @@ -20,28 +21,8 @@ require([ $book.find(".count-watch span").text(repo.subscribers_count); }); - // Bind exercises - $book.find("section.exercise").each(function() { - var $exercise = $(this); - - var codeSolution = $exercise.find(".code-solution").html(); - var codeValidation = $exercise.find(".code-validation").html(); - - var editor = ace.edit($exercise.find(".editor").get(0)); - editor.setTheme("ace/theme/tomorrow"); - editor.getSession().setMode("ace/mode/javascript"); - - $exercise.find(".action-submit").click(function(e) { - e.preventDefault(); - - alert("submit"); - }); - $exercise.find(".action-solution").click(function(e) { - e.preventDefault(); - - editor.setValue(codeSolution); - }); - }); + // Bind exercise + exercise.init(); // Show progress progress.show(); diff --git a/assets/javascript/core/exercise.js b/assets/javascript/core/exercise.js new file mode 100644 index 0000000..153f544 --- /dev/null +++ b/assets/javascript/core/exercise.js @@ -0,0 +1,45 @@ +define([ + "jQuery", + "utils/execute", + "core/state" +], function($, execute, state){ + // Bind an exercise + var prepareExercise = function($exercise) { + var codeSolution = $exercise.find(".code-solution").html(); + var codeValidation = $exercise.find(".code-validation").html(); + + var editor = ace.edit($exercise.find(".editor").get(0)); + editor.setTheme("ace/theme/tomorrow"); + editor.getSession().setMode("ace/mode/javascript"); + + // Submit: test code + $exercise.find(".action-submit").click(function(e) { + e.preventDefault(); + + execute(editor.getValue(), codeValidation, function(err, result) { + $exercise.toggleClass("return-error", err != null); + $exercise.toggleClass("return-success", err == null); + if (err) $exercise.find(".alert-danger").text(err.message || err); + }); + }); + + // Set solution + $exercise.find(".action-solution").click(function(e) { + e.preventDefault(); + + editor.setValue(codeSolution); + }); + }; + + // Prepare all exercise + var init = function() { + state().$book.find("section.exercise").each(function() { + prepareExercise($(this)); + }); + }; + + return { + init: init, + prepare: prepareExercise + }; +});
\ No newline at end of file diff --git a/assets/javascript/utils/execute.js b/assets/javascript/utils/execute.js new file mode 100644 index 0000000..ba4192d --- /dev/null +++ b/assets/javascript/utils/execute.js @@ -0,0 +1,91 @@ +define(function(){ + var evalJS = function(code, callback) { + var ready = false; + var finished = false; + + var finish = function() { + if(finished) { + return console.error('Already finished'); + } + finished = true; + return callback.apply(null, arguments); + }; + + var jsrepl; + + // Handles all our events + var eventHandler = function(data, eventType) { + console.log([eventType, data]); + switch(eventType) { + case 'progress': + // Update UI loading bar + break; + case 'timeout': + finish(new Error(data)); + break; + case 'result': + finish(null, { + value: data, + type: 'result' + }); + break; + case 'error': + if(ready) { + return finish(null, { + value: data, + type: 'error' + }); + } + return finish(new Error(data)); + break + case 'ready': + // We're good to get results and stuff back now + ready = true; + // Eval our code now that the runtime is ready + jsrepl.eval(code); + break; + default: + console.log('Unhandled event =', eventType, 'data =', data); + } + }; + + jsrepl = new JSREPL({ + input: eventHandler, + output: eventHandler, + result: eventHandler, + error: eventHandler, + progress: eventHandler, + timeout: { + time: 30000, + callback: eventHandler + } + }); + + jsrepl.loadLanguage('javascript', eventHandler); + }; + + + var ass = "function assert(condition, message) { \nif (!condition) { \n throw message || \"Assertion failed\"; \n } \n }\n"; + + var code = { + "base": "var firstName = \"John\";\nvar middleName = \"James\";\nvar lastName = \"Smith\";\n\nvar fullName =", + "solution": "var firstName = \"John\";\nvar middleName = \"James\";\nvar lastName = \"Smith\";\n\nvar fullName = firstName + \" \" + middleName + \" \" + lastName;", + "validation": "console.log(fullName); assert(fullName == 'John James Smith');" + }; + + var execute = function(solution, validation, callback) { + evalJS(solution + ass + validation, function(err, res) { + if(err) { + return callback(err); + } + console.log('validation =', res); + if (res.type == "error") { + callback(new Error(res.value)); + } else { + callback(null, res.value); + } + }); + }; + + return execute; +});
\ No newline at end of file |