mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-21 10:03:31 +00:00
Add execution of exercise
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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
|
||||
};
|
||||
});
|
||||
@@ -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;
|
||||
});
|
||||
Reference in New Issue
Block a user