summaryrefslogtreecommitdiffstats
path: root/assets/javascript
diff options
context:
space:
mode:
Diffstat (limited to 'assets/javascript')
-rw-r--r--assets/javascript/app.js29
-rw-r--r--assets/javascript/core/exercise.js45
-rw-r--r--assets/javascript/utils/execute.js91
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