/* globals jailed, CodeMirror, challenge_Id, challenge_Name, challengeType */ // codeStorage var codeStorageFactory = (function($, localStorage) { var CodeStorageProps = { version: 0.01, keyVersion: 'saveVersion', keyValue: null, updateWait: 2000, updateTimeoutId: null }; var CodeStorage = { hasSaved: function() { return this.updateTimeoutId === null; }, onSave: function(func) { this.eventArray.push(func); }, setSaveKey: function(key) { this.keyValue = key + 'Val'; }, getStoredValue: function() { return '' + localStorage.getItem(this.keyValue); }, setEditor: function(editor) { this.editor = editor; }, isAlive: function() { var val = this.getStoredValue(); return val !== 'null' && val !== 'undefined' && (val && val.length > 0); }, updateStorage: function() { if (typeof localStorage !== 'undefined') { var value = this.editor.getValue(); localStorage.setItem(this.keyValue, value); } else { console.log('no web storage'); } this.updateTimeoutId = null; } }; function codeStorageFactory(editor, challengeName) { var codeStorage = Object.create(CodeStorage); $.extend(codeStorage, CodeStorageProps); codeStorage.setEditor(editor); codeStorage.setSaveKey(challengeName); return codeStorage; } var savedVersion = localStorage.getItem(CodeStorageProps.keyVersion); if (savedVersion === null) { localStorage.setItem( CodeStorageProps.keyVersion, CodeStorageProps.version ); } return codeStorageFactory; }($, localStorage)); var sandBox = (function() { var plugin = null; var sandBox = { }; var printCallback; // sends the input to the plugin for evaluation function submit(code, callback) { printCallback = callback; // postpone the evaluation until the plugin is initialized plugin.whenConnected(function() { if (requests === 0) { startLoading(); } requests++; plugin.remote.run(code); }); } // puts the message on the terminal var print = function(cls, msg) { printCallback(cls, msg); }; // will restart the plugin if it does not respond var disconnectTimeout = null; var startLoading = function() { disconnectTimeout = setTimeout(disconnect, 3000); }; var endLoading = function() { clearTimeout(disconnectTimeout); }; var disconnect = function() { plugin.disconnect(); }; // interface provided to the plugin var api = { output: function(data) { endLoading(); // print('input', data.input); if (data.error) { print('Error', data); reset(); } else { print(null, data); reset(); } } }; // obtaining absolute path of this script var scripts = document.getElementsByTagName('script'); var path = scripts[scripts.length - 1].src .split('?')[0] .split('/') .slice(0, -1) .join('/') + '/'; var requests; // (re)initializes the plugin var reset = function() { requests = 0; plugin = new jailed.Plugin(path + 'plugin.js', api); plugin.whenDisconnected( function() { // give some time to handle the last responce setTimeout( function() { endLoading(); console.log('resetting on fatal plugin error'); if (challengeType === 0) { codeOutput.setValue( 'Sorry, your code is either too slow, has a fatal error, ' + 'or contains an infinite loop.' ); } reset(); }, 10); }); }; reset(); sandBox.submit = submit; return sandBox; }()); function replaceSafeTags(value) { return value .replace(/fccss/gi, ''); } var BDDregex = new RegExp( '(expect(\\s+)?\\(.*\\;)|' + '(assert(\\s+)?\\(.*\\;)|' + '(assert\\.\\w.*\\;)|' + '(.*\\.should\\..*\\;)/' ); var isInitRun = false; var initPreview = true; var editor; editor = CodeMirror.fromTextArea(document.getElementById('codeEditor'), { lineNumbers: true, mode: 'text', theme: 'monokai', runnable: true, matchBrackets: true, autoCloseBrackets: true, scrollbarStyle: 'null', lineWrapping: true, gutters: ['CodeMirror-lint-markers'] }); var codeStorage = codeStorageFactory(editor, challenge_Name); var myCodeMirror = editor; editor.on('keyup', function() { clearTimeout(codeStorage.updateTimeoutId); codeStorage.updateTimeoutId = setTimeout( codeStorage.updateStorage.bind(codeStorage), codeStorage.updateWait ); }); var editorValue; var challengeSeed = challengeSeed || null; var tests = tests || []; var allSeeds = ''; (function() { challengeSeed.forEach(function(elem) { allSeeds += elem + '\n'; }); })(); if (typeof emmetCodeMirror !== 'undefined') { var defaultKeymap = { 'Cmd-E': 'emmet.expand_abbreviation', 'Tab': 'emmet.expand_abbreviation_with_tab', 'Enter': 'emmet.insert_formatted_line_break_only' }; emmetCodeMirror(editor, defaultKeymap); } 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(true); return false; } }); editor.setSize('100%', 'auto'); var libraryIncludes = "" + "" + "" + "" + "" + "" + "" + '' + ''; var editorValueForIFrame; var iFrameScript = ""; var delay; function workerError(error) { var display = $('.runTimeError'); var housing = $('#testSuite'); if (display.html() !== error) { display.remove(); housing.prepend( '
' +
error.replace(/j\$/gi, '$').replace(/jdocument/gi, 'document').replace(/jjQuery/gi, 'jQuery') +
'