window.CodeExecutor = Spine.Class.create({
init: function() { this.visibleCodeBlocks = {}; this.executeCodeFor = {} $.subscribe("code:execute",$.proxy(function(e,code) { this.executeCode(code); },this)); $.subscribe("code:execute:visible",$.proxy(function(e,code) { this.executeVisibleCode(); },this)); }, registerVisibleCodeBlock: function(language,elements,execution) { this.visibleCodeBlocks[language] = elements; this.executeCodeFor[language] = execution; }, executeVisibleCode: function() { var codeBlocks = this.visibleCodeBlocks(); var supportedCodeBlockLanguages = Object.keys(codeBlocks); for (var i = 0; i < supportedCodeBlockLanguages.length; i++) { var lang = supportedCodeBlockLanguages[i]; if (codeBlocks[lang].length > 0) { var code = codeBlocks[lang].text(); this.executeCode({ lang: lang, code: code }); } } }, executeCode: function(code) { var codeExecutor = this.executorForLanguage(code['lang']); $.publish('code:execution:started'); codeExecutor(code['code']); }, executorForLanguage: function(language) { return this.executeCodeFor[language]; }
});
window.CodeViewer = Spine.Class.create({
init: function() { $.subscribe("code:execution:started",$.proxy(function(e) { this.printResults("Executing..."); },this)); $.subscribe("code:execution:finished",$.proxy(function(e) { // When the execution is finished there is nothing that needs // to happen at the moment },this)); $.subscribe("code:execution:results",$.proxy(function(e,result) { this.printResults(result); },this)); $.subscribe("code:execution:clear",$.proxy(function(e,result) { this.removeResults(); },this)); this.resultsView = $('.results'); this.resultsView.live('click',function() { $(this).hide(); }); }, toggle: function() { }, printResults: function(result) { var formattedResults = $.print(result, {max_string:500}); this.removeResults(); this.resultsView.show(); this.resultsView.html(formattedResults) }, removeResults: function() { this.resultsView.html(""); this.resultsView.hide(); }
})
$(document).ready(function() {
codeExecutor = new CodeExecutor; codeViewer = new CodeViewer; codeExecutor.registerVisibleCodeBlock('js',$('.execute .javascript pre:visible'),function(code) { var result = eval(code); setTimeout(function() { $.publish('code:execution:finished'); }, 250 ); if (result != null) { $.publish('code:execution:results',result); } }); $('.execute pre.javascript').live("click", function() { var code = $(this).text(); $.publish('code:execute',{ lang: 'js', code: code, elem: $(this) }); }); codeExecutor.registerVisibleCodeBlock('coffee',$('.execute .coffeescript pre:visible'), function(code) { // When Coffeescript completes it's work the final result is encapsulated // within it. To get around it, the result of the last evaluation needs to // be assigned to the window, which we can then use for the purposes of // displaying the results. var codeWithAssignmentToResults = code + ';window.result=result;' eval(CoffeeScript.compile(codeWithAssignmentToResults)); setTimeout(function() { $.publish('code:execution:finished'); }, 250 ); if (result != null) { $.publish('code:execution:results',result); } }); $('.execute pre.coffeescript').live("click", function() { var code = $(this).text(); $.publish('code:execute',{ lang: 'coffee', code: code, elem: $(this) }); });
});