diff --git a/app.js b/app.js index 1b00f76de3..24b87bf777 100644 --- a/app.js +++ b/app.js @@ -261,6 +261,8 @@ app.get( bonfireController.returnIndividualBonfire ); app.get('/bonfires', bonfireController.returnBonfire); +app.get('/bonfire/generator', bonfireController.returnGenerator); +app.post('/bonfire/generator', bonfireController.generateChallenge); // Unique Check API route app.get('/api/checkUniqueUsername/:username', userController.checkUniqueUsername); diff --git a/controllers/bonfire.js b/controllers/bonfire.js index b669452ab0..264c688281 100644 --- a/controllers/bonfire.js +++ b/controllers/bonfire.js @@ -95,4 +95,96 @@ exports.returnIndividualBonfire = function(req, res, next) { bonfireHash: bonfire[bonfireNumber]._id }); }); -}; \ No newline at end of file +}; + +/** + * Bonfire generator + */ +exports.returnGenerator = function(req, res) { + res.render('bonfire/generator', { + title: null, + name: null, + difficulty: null, + brief: null, + details: null, + tests: null, + challengeSeed: null, + challengeEntryPoint: null, + bonfireHash: randomString() + }); +}; + +/** + * Post for bonfire generation + */ + +function randomString() { + var chars = "0123456789abcdef"; + var string_length = 24; + var randomstring = ''; + for (var i=0; i 0) { + return elem; + } +} + +exports.generateChallenge = function(req, res) { + var bonfireName = req.body.name, + bonfireTests = req.body.tests, + bonfireDifficulty = req.body.difficulty, + bonfireDescription = req.body.description, + bonfireEntryPoint = req.body.challengeEntryPoint, + bonfireChallengeSeed = req.body.challengeSeed; + bonfireTests = bonfireTests.split('\r\n'); + bonfireDescription = bonfireDescription.split('\r\n'); + bonfireTests.filter(getRidOfEmpties); + bonfireDescription.filter(getRidOfEmpties); + bonfireChallengeSeed = bonfireChallengeSeed.replace('\r', ''); + + + var response = { + name: bonfireName, + tests: bonfireTests, + difficulty: bonfireDifficulty, + description: bonfireDescription, + challengeEntryPoint: bonfireEntryPoint, + challengeSeed: bonfireChallengeSeed, + bonfireNumber: 0, + _id: randomString() + }; + res.send(response); +} diff --git a/public/css/main.less b/public/css/main.less index 23fcc5c631..d9c9cd4ab0 100644 --- a/public/css/main.less +++ b/public/css/main.less @@ -579,7 +579,16 @@ form.code span { font-family: "Ubuntu Mono"; padding-bottom: 0px; margin-bottom: 0px; - height: auto; + height: 100%; +} + +.CodeMirror-linenumber { + font-size: 18px; + font-family: "Ubuntu Mono"; +} + +#mainEditorPanel { + height: 100%; } .big-error-icon { @@ -606,13 +615,15 @@ form.code span { } div.CodeMirror-scroll { - padding-bottom: 100px; + padding-bottom: 40px; } .test-vertical-center { margin-top: 15px; } + + //uncomment this to see the dimensions of all elements outlined in red //* { // border-color: red; diff --git a/public/js/lib/bonfire/bonfireFramework.js b/public/js/lib/bonfire/bonfireFramework.js index 45ac46ca0e..8d8705cf0c 100644 --- a/public/js/lib/bonfire/bonfireFramework.js +++ b/public/js/lib/bonfire/bonfireFramework.js @@ -7,7 +7,6 @@ var myCodeMirror = CodeMirror.fromTextArea(document.getElementById("codeEditor") lint: true, matchBrackets: true, autoCloseBrackets: true, - cursorHeight: 1, scrollbarStyle: 'null', lineWrapping: true, gutters: ["CodeMirror-lint-markers"], @@ -20,6 +19,7 @@ var myCodeMirror = CodeMirror.fromTextArea(document.getElementById("codeEditor") } }); var editor = myCodeMirror; +editor.setSize("100%", "auto"); // Default value for editor if one isn't provided in (i.e. a challenge) @@ -37,7 +37,8 @@ var nonChallengeValue = '/*Welcome to Bonfire, Free Code Camp\'s future CoderByt 'assert.deepEqual(test(), [1,4,9]);\n\n' + 'var foo = test();\n' + 'foo.should.be.a("array");\n\n' + - 'test();'; + 'test();\n' + + 'function test(str) {\r\n return str;\r\n}'; var codeOutput = CodeMirror.fromTextArea(document.getElementById("codeOutput"), { lineNumbers: false, @@ -106,6 +107,8 @@ function bonfireExecute() { var userJavaScript = myCodeMirror.getValue(); userJavaScript = removeComments(userJavaScript); userJavaScript = scrapeTests(userJavaScript); + // simple fix in case the user forgets to invoke their function + userJavaScript = challengeEntryPoint + ' ' + userJavaScript; submit(userJavaScript, function(cls, message) { if (cls) { codeOutput.setValue(message.error); diff --git a/seed_data/bonfires.json b/seed_data/bonfires.json index db847aecea..42778c1e5e 100644 --- a/seed_data/bonfires.json +++ b/seed_data/bonfires.json @@ -15,8 +15,7 @@ ], "challengeSeed": "function meetBonfire(argument) {\n // Good luck!\n console.log(\"you can read this function's argument in the developer tools\", argument);\n\nreturn false;\n}\n\n", "challengeEntryPoint": "meetBonfire(\"You can do this!\");", - "bonfireNumber": 0, - "challengeEntryPointNegate" : "meetBonfire(\"You can do this!\");" + "bonfireNumber": 0 }, { "_id" : "aaa48de84e1ecc7c742e1124", @@ -40,8 +39,7 @@ ], "challengeSeed": "function palindrome(str) {\n // Good luck!\n return true;\n}\n\n", "challengeEntryPoint": "palindrome(\"eye\");", - "bonfireNumber": 1, - "challengeEntryPointNegate" : "palindrome\\([^str].*\\;" + "bonfireNumber": 1 }, { "_id" : "ff0395860f5d3034dc0bfc94", @@ -79,8 +77,7 @@ ], "challengeSeed": "function telephoneCheck(str) {\n // Good luck!\n return true;\n}\n\n", "challengeEntryPoint": "telephoneCheck(\"555-555-5555\");", - "bonfireNumber": 2, - "challengeEntryPointNegate" : "palindrome\\([^str].*\\;" + "bonfireNumber": 2 } ] diff --git a/seed_data/challenge-hashes b/seed_data/challenge-hashes index ca100cb520..64932960ca 100644 --- a/seed_data/challenge-hashes +++ b/seed_data/challenge-hashes @@ -1,7 +1,7 @@ /* -"c3a4d278b9e760a0ffe8321f" + "aceca143b92049a4392a859e" "ce9394f67d413734758e27e4" "1369953ef6f03098cb60e2f7" diff --git a/views/bonfire/generator.jade b/views/bonfire/generator.jade new file mode 100644 index 0000000000..bc150870a1 --- /dev/null +++ b/views/bonfire/generator.jade @@ -0,0 +1,45 @@ +extends ../layout +block content + .row + .col-md-offset-2.col-md-8.col-lg-offset-2.col-lg-8.text-center + + h1 JSON generator for bonfire challenges - just fill the form out and get the correct format back + .col-xs-12.col-sm-12.col-md-offset-3.col-md-6.col-lg-offset-3-col-lg-6 + .panel + form.form-horizontal(method="POST", action="/bonfire/generator", name="bonfireInfo") + .form-group + label.col-sm-2.control-label(for='name') name: + .col-sm-10 + input#name.form-control(type='text', placeholder='name', name="name") + .form-group + label.col-sm-2.control-label(for='difficultyField') difficulty: + .col-sm-10 + label.radio-inline 1 + input#inlineRadio1(type='radio', name='difficulty', value='1') + label.radio-inline 2 + input#inlineRadio2(type='radio', name='difficulty', value='2') + label.radio-inline 3 + input#inlineRadio3(type='radio', name='difficulty', value='3') + label.radio-inline 4 + input#inlineRadio4(type='radio', name='difficulty', value='4') + label.radio-inline 5 + input#inlineRadio5(type='radio', name='difficulty', value='5') + .form-group + label.col-sm-2.control-label.wrappable(for='description') description: + .col-sm-10 + textarea#description.form-control(name="description", placeholder="Separate sentences by exactly one space only. Do not add in line breaks.") + .form-group + label.col-sm-2.control-label.wrappable(for='tests') tests: + .col-sm-10 + textarea#tests.form-control(name="tests", rows=5, placeholder="Separate tests by a newline.") + .form-group + label.col-sm-2.control-label.wrappable(for='challengeSeed') challengeSeed: + .col-sm-10 + textarea#challengeSeed.form-control(name="challengeSeed", rows=5) + .form-group + label.col-sm-2.control-label.wrappable(for='challengeEntryPoint') challenge entrypoint: + .col-sm-10 + textarea#name.form-control(name="challengeEntryPoint", rows=1, type='text', placeholder="palindrome(\"eye\");") + .form-group + .col-sm-offset-2.col-sm-10 + input.btn.btn-default(type='submit', value="submit")