diff --git a/.eslintrc b/.eslintrc index 5d7667557f..92fad475c3 100644 --- a/.eslintrc +++ b/.eslintrc @@ -224,8 +224,8 @@ "no-plusplus": 0, "react/display-name": 1, - "react/jsx-boolean-value": 1, - "react/jsx-quotes": [1, "single", "avoid-escape"], + "react/jsx-boolean-value": [1, "always"], + "jsx-quotes": [1, "prefer-single"], "react/jsx-no-undef": 1, "react/jsx-sort-props": 1, "react/jsx-uses-react": 1, diff --git a/Procfile b/Procfile deleted file mode 100644 index 7769836542..0000000000 --- a/Procfile +++ /dev/null @@ -1 +0,0 @@ -web: ./node_modules/.bin/forever -m 5 server.js \ No newline at end of file diff --git a/README.md b/README.md index 0611cd1816..c81c0bb1e3 100644 --- a/README.md +++ b/README.md @@ -4,23 +4,25 @@ [![Join the chat at https://gitter.im/freecodecamp/freecodecamp](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/freecodecamp/freecodecamp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -Welcome to Free Code Camp's open source codebase! +Welcome to Free Code Camp's open source codebase and curriculum! ======================= -Free Code Camp is an open-source community of busy people who learn to code and build projects for nonprofits. +Free Code Camp is an open-source community where you learn to code and help nonprofits. -Our campers (students) start by working through our free, self-paced, browser-based curriculum. Next, they build several practice projects. Finally, we pair two campers together with a stakeholder from a nonprofit organization, and help them build the solution the nonprofit has requested. +You start by working through our self-paced, browser-based full stack JavaScript curriculum. + +After you complete the first 400 hours worth of challenges (which involves building 10 single-page apps), you'll earn your Front End Development Certification. + +After you complete the second 400 hours worth of challenges (which involves building and deploying 5 full stack apps), you'll earn your Full Stack Development Certification. + +Then we'll pair you with another camper, an agile project manager, and a stakeholder from a nonprofit organization. Together, you'll plan and build an app that helps that nonprofit carry out its mission more effectively. **We help our campers build job-worthy portfolios of real apps used by real people, while helping nonprofits.** -80% of our campers are over 25, and nearly a fifth of our campers are women. - -This code is running live at [FreeCodeCamp.com](http://www.FreeCodeCamp.com). We also have [Gitter](https://gitter.im/FreeCodeCamp/FreeCodeCamp), a [blog](http://medium.freecodecamp.com), and even a [Twitch.tv channel](http://twitch.tv/freecodecamp). +This code is running live at [FreeCodeCamp.com](http://www.FreeCodeCamp.com). We also have [Gitter](https://gitter.im/FreeCodeCamp/FreeCodeCamp), a [Medium publication](http://medium.freecodecamp.com), and even a [Twitch.tv channel](http://twitch.tv/freecodecamp). [Join our community here](http://www.freecodecamp.com/signin). -*Note: We're currently very close to moving from Express to Loopback. As such, please keep in mind that the instructions here for setting up and running the project do not directly translate to the staging branch. Additionally, the file structure is quite a bit different. As always, the staging branch is the appropriate place to branch off of to fix/add something.* - Wiki ------------ diff --git a/client/commonFramework.js b/client/commonFramework.js index 20ba4b40e1..7b1865d56a 100644 --- a/client/commonFramework.js +++ b/client/commonFramework.js @@ -7,23 +7,25 @@ var common = (function() { init: [] }; - common.challengeName = common.challengeName || window.challenge_Name ? - window.challenge_Name : - ''; + common.challengeName = common.challengeName || window.challenge_Name || ''; - common.challengeType = common.challengeType || window.challengeType ? - window.challengeType : - 0; + common.challengeType = common.challengeType || window.challengeType || 0; common.challengeId = common.challengeId || window.challenge_Id; - common.challengeSeed = common.challengeSeed || window.challengeSeed ? - window.challengeSeed : - []; + common.challengeSeed = common.challengeSeed || window.challengeSeed || []; - common.seed = common.challengeSeed.reduce(function(seed, line) { - return seed + line + '\n'; - }, ''); + common.head = common.head || ''; + common.tail = common.tail || ''; + + common.arrayToNewLineString = function arrayToNewLineString(seedData) { + seedData = Array.isArray(seedData) ? seedData : [seedData]; + return seedData.reduce(function(seed, line) { + return '' + seed + line + '\n'; + }, ''); + }; + + common.seed = common.arrayToNewLineString(common.challengeSeed); common.replaceScriptTags = function replaceScriptTags(value) { return value @@ -136,8 +138,16 @@ common.codeUri = (function(common, encode, decode, location, history) { if (!codeUri.enabled) { return null; } - location.hash = '?solution=' + - codeUri.encode(encodeFcc(solution)); + if (history && typeof history.replaceState === 'function') { + history.replaceState( + history.state, + null, + '?solution=' + codeUri.encode(encodeFcc(solution)) + ); + } else { + location.hash = '?solution=' + + codeUri.encode(encodeFcc(solution)); + } return solution; }, @@ -474,17 +484,24 @@ var editor = (function(CodeMirror, emmetCodeMirror, common) { }(window.CodeMirror, window.emmetCodeMirror, common)); -var tests = tests || []; +var tests = common.tests || []; -var libraryIncludes = "" + - "" + - "" + - "" + - "" + - "" + - "" + - '' + - ''; +var libraryIncludes = + "' + + "" + + "" + + "" + + "" + + "" + + "" + + '' + + ''; var editorValueForIFrame; var iFrameScript = ""; @@ -498,9 +515,13 @@ function workerError(error) { housing.prepend( '
' + - error.replace(/j\$/gi, '$').replace(/jdocument/gi, 'document').replace(/jjQuery/gi, 'jQuery') + + error + .replace(/j\$/gi, '$') + .replace(/jdocument/gi, 'document') + .replace(/jjQuery/gi, 'jQuery') + '
' ); + display.hide().fadeIn(function() { setTimeout(function() { display.fadeOut(function() { @@ -533,21 +554,269 @@ function safeHTMLRun(test) { .split(/\<\s?\/\s?script\s?\>/gi)[0]; // add feuxQuery - s = 'var document = \"\"; var $ = function() {return(new function() {this.add=function() {return(this);};this.addBack=function() {return(this);};this.addClass=function() {return(this);};this.after=function() {return(this);};this.ajaxComplete=function() {return(this);};this.ajaxError=function() {return(this);};this.ajaxSend=function() {return(this);};this.ajaxStart=function() {return(this);};this.ajaxStop=function() {return(this);};this.ajaxSuccess=function() {return(this);};this.andSelf=function() {return(this);};this.animate=function() {return(this);};this.append=function() {return(this);};this.appendTo=function() {return(this);};this.attr=function() {return(this);};this.before=function() {return(this);};this.bind=function() {return(this);};this.blur=function() {return(this);};this.callbacksadd=function() {return(this);};this.callbacksdisable=function() {return(this);};this.callbacksdisabled=function() {return(this);};this.callbacksempty=function() {return(this);};this.callbacksfire=function() {return(this);};this.callbacksfired=function() {return(this);};this.callbacksfireWith=function() {return(this);};this.callbackshas=function() {return(this);};this.callbackslock=function() {return(this);};this.callbackslocked=function() {return(this);};this.callbacksremove=function() {return(this);};this.change=function() {return(this);};this.children=function() {return(this);};this.clearQueue=function() {return(this);};this.click=function() {return(this);};this.clone=function() {return(this);};this.closest=function() {return(this);};this.contents=function() {return(this);};this.context=function() {return(this);};this.css=function() {return(this);};this.data=function() {return(this);};this.dblclick=function() {return(this);};this.delay=function() {return(this);};this.delegate=function() {return(this);};this.dequeue=function() {return(this);};this.detach=function() {return(this);};this.die=function() {return(this);};this.each=function() {return(this);};this.empty=function() {return(this);};this.end=function() {return(this);};this.eq=function() {return(this);};this.error=function() {return(this);};this.fadeIn=function() {return(this);};this.fadeOut=function() {return(this);};this.fadeTo=function() {return(this);};this.fadeToggle=function() {return(this);};this.filter=function() {return(this);};this.find=function() {return(this);};this.finish=function() {return(this);};this.first=function() {return(this);};this.focus=function() {return(this);};this.focusin=function() {return(this);};this.focusout=function() {return(this);};this.get=function() {return(this);};this.has=function() {return(this);};this.hasClass=function() {return(this);};this.height=function() {return(this);};this.hide=function() {return(this);};this.hover=function() {return(this);};this.html=function() {return(this);};this.index=function() {return(this);};this.innerHeight=function() {return(this);};this.innerWidth=function() {return(this);};this.insertAfter=function() {return(this);};this.insertBefore=function() {return(this);};this.is=function() {return(this);};this.jQuery=function() {return(this);};this.jquery=function() {return(this);};this.keydown=function() {return(this);};this.keypress=function() {return(this);};this.keyup=function() {return(this);};this.last=function() {return(this);};this.length=function() {return(this);};this.live=function() {return(this);};this.load=function() {return(this);};this.load=function() {return(this);};this.map=function() {return(this);};this.mousedown=function() {return(this);};this.mouseenter=function() {return(this);};this.mouseleave=function() {return(this);};this.mousemove=function() {return(this);};this.mouseout=function() {return(this);};this.mouseover=function() {return(this);};this.mouseup=function() {return(this);};this.next=function() {return(this);};this.nextAll=function() {return(this);};this.nextUntil=function() {return(this);};this.not=function() {return(this);};this.off=function() {return(this);};this.offset=function() {return(this);};this.offsetParent=function() {return(this);};this.on=function() {return(this);};this.one=function() {return(this);};this.outerHeight=function() {return(this);};this.outerWidth=function() {return(this);};this.parent=function() {return(this);};this.parents=function() {return(this);};this.parentsUntil=function() {return(this);};this.position=function() {return(this);};this.prepend=function() {return(this);};this.prependTo=function() {return(this);};this.prev=function() {return(this);};this.prevAll=function() {return(this);};this.prevUntil=function() {return(this);};this.promise=function() {return(this);};this.prop=function() {return(this);};this.pushStack=function() {return(this);};this.queue=function() {return(this);};this.ready=function() {return(this);};this.remove=function() {return(this);};this.removeAttr=function() {return(this);};this.removeClass=function() {return(this);};this.removeData=function() {return(this);};this.removeProp=function() {return(this);};this.replaceAll=function() {return(this);};this.replaceWith=function() {return(this);};this.resize=function() {return(this);};this.scroll=function() {return(this);};this.scrollLeft=function() {return(this);};this.scrollTop=function() {return(this);};this.select=function() {return(this);};this.selector=function() {return(this);};this.serialize=function() {return(this);};this.serializeArray=function() {return(this);};this.show=function() {return(this);};this.siblings=function() {return(this);};this.size=function() {return(this);};this.slice=function() {return(this);};this.slideDown=function() {return(this);};this.slideToggle=function() {return(this);};this.slideUp=function() {return(this);};this.stop=function() {return(this);};this.submit=function() {return(this);};this.text=function() {return(this);};this.toArray=function() {return(this);};this.toggle=function() {return(this);};this.toggle=function() {return(this);};this.toggleClass=function() {return(this);};this.trigger=function() {return(this);};this.triggerHandler=function() {return(this);};this.unbind=function() {return(this);};this.undelegate=function() {return(this);};this.unload=function() {return(this);};this.unwrap=function() {return(this);};this.val=function() {return(this);};this.width=function() {return(this);};this.wrap=function() {return(this);};this.wrapAll=function() {return(this);};this.wrapInner=function() {return(this);}});};$.ajax=function() {return($);};$.ajaxPrefilter=function() {return($);};$.ajaxSetup=function() {return($);};$.ajaxTransport=function() {return($);};$.boxModel=function() {return($);};$.browser=function() {return($);};$.Callbacks=function() {return($);};$.contains=function() {return($);};$.cssHooks=function() {return($);};$.cssNumber=function() {return($);};$.data=function() {return($);};$.Deferred=function() {return($);};$.dequeue=function() {return($);};$.each=function() {return($);};$.error=function() {return($);};$.extend=function() {return($);};$.fnextend=function() {return($);};$.fxinterval=function() {return($);};$.fxoff=function() {return($);};$.get=function() {return($);};$.getJSON=function() {return($);};$.getScript=function() {return($);};$.globalEval=function() {return($);};$.grep=function() {return($);};$.hasData=function() {return($);};$.holdReady=function() {return($);};$.inArray=function() {return($);};$.isArray=function() {return($);};$.isEmptyObject=function() {return($);};$.isFunction=function() {return($);};$.isNumeric=function() {return($);};$.isPlainObject=function() {return($);};$.isWindow=function() {return($);};$.isXMLDoc=function() {return($);};$.makeArray=function() {return($);};$.map=function() {return($);};$.merge=function() {return($);};$.noConflict=function() {return($);};$.noop=function() {return($);};$.now=function() {return($);};$.param=function() {return($);};$.parseHTML=function() {return($);};$.parseJSON=function() {return($);};$.parseXML=function() {return($);};$.post=function() {return($);};$.proxy=function() {return($);};$.queue=function() {return($);};$.removeData=function() {return($);};$.sub=function() {return($);};$.support=function() {return($);};$.trim=function() {return($);};$.type=function() {return($);};$.unique=function() {return($);};$.when=function() {return($);};$.always=function() {return($);};$.done=function() {return($);};$.fail=function() {return($);};$.isRejected=function() {return($);};$.isResolved=function() {return($);};$.notify=function() {return($);};$.notifyWith=function() {return($);};$.pipe=function() {return($);};$.progress=function() {return($);};$.promise=function() {return($);};$.reject=function() {return($);};$.rejectWith=function() {return($);};$.resolve=function() {return($);};$.resolveWith=function() {return($);};$.state=function() {return($);};$.then=function() {return($);};$.currentTarget=function() {return($);};$.data=function() {return($);};$.delegateTarget=function() {return($);};$.isDefaultPrevented=function() {return($);};$.isImmediatePropagationStopped=function() {return($);};$.isPropagationStopped=function() {return($);};$.metaKey=function() {return($);};$.namespace=function() {return($);};$.pageX=function() {return($);};$.pageY=function() {return($);};$.preventDefault=function() {return($);};$.relatedTarget=function() {return($);};$.result=function() {return($);};$.stopImmediatePropagation=function() {return($);};$.stopPropagation=function() {return($);};$.target=function() {return($);};$.timeStamp=function() {return($);};$.type=function() {return($);};$.which=function() {return($);};' + s; + s = 'var document = ""; ' + + 'var $ = function() {' + + 'return new function() { this.add=function() { return this; };' + + 'this.addBack=function() {return this; };' + + 'this.addClass=function() {return this; };' + + 'this.after=function() {return this; };' + + 'this.ajaxComplete=function() {return this; };' + + 'this.ajaxError=function() {return this; };' + + 'this.ajaxSend=function() {return this; };' + + 'this.ajaxStart=function() {return this; };' + + 'this.ajaxStop=function() {return this; };' + + 'this.ajaxSuccess=function() {return this; };' + + 'this.andSelf=function() {return this; };' + + 'this.animate=function() {return this; };' + + 'this.append=function() {return this; };' + + 'this.appendTo=function() {return this; };' + + 'this.attr=function() {return this; };' + + 'this.before=function() {return this; };' + + 'this.bind=function() {return this; };' + + 'this.blur=function() {return this; };' + + 'this.callbacksadd=function() {return this; };' + + 'this.callbacksdisable=function() {return this; };' + + 'this.callbacksdisabled=function() {return this; };' + + 'this.callbacksempty=function() {return this; };' + + 'this.callbacksfire=function() {return this; };' + + 'this.callbacksfired=function() {return this; };' + + 'this.callbacksfireWith=function() {return this; };' + + 'this.callbackshas=function() {return this; };' + + 'this.callbackslock=function() {return this; };' + + 'this.callbackslocked=function() {return this; };' + + 'this.callbacksremove=function() {return this; };' + + 'this.change=function() {return this; };' + + 'this.children=function() {return this; };' + + 'this.clearQueue=function() {return this; };' + + 'this.click=function() {return this; };' + + 'this.clone=function() {return this; };' + + 'this.closest=function() {return this; };' + + 'this.contents=function() {return this; };' + + 'this.context=function() {return this; };' + + 'this.css=function() {return this; };' + + 'this.data=function() {return this; };' + + 'this.dblclick=function() {return this; };' + + 'this.delay=function() {return this; };' + + 'this.delegate=function() {return this; };' + + 'this.dequeue=function() {return this; };' + + 'this.detach=function() {return this; };' + + 'this.die=function() {return this; };' + + 'this.each=function() {return this; };' + + 'this.empty=function() {return this; };' + + 'this.end=function() {return this; };' + + 'this.eq=function() {return this; };' + + 'this.error=function() {return this; };' + + 'this.fadeIn=function() {return this; };' + + 'this.fadeOut=function() {return this; };' + + 'this.fadeTo=function() {return this; };' + + 'this.fadeToggle=function() {return this; };' + + 'this.filter=function() {return this; };' + + 'this.find=function() {return this; };' + + 'this.finish=function() {return this; };' + + 'this.first=function() {return this; };' + + 'this.focus=function() {return this; };' + + 'this.focusin=function() {return this; };' + + 'this.focusout=function() {return this; };' + + 'this.get=function() {return this; };' + + 'this.has=function() {return this; };' + + 'this.hasClass=function() {return this; };' + + 'this.height=function() {return this; };' + + 'this.hide=function() {return this; };' + + 'this.hover=function() {return this; };' + + 'this.html=function() {return this; };' + + 'this.index=function() {return this; };' + + 'this.innerHeight=function() {return this; };' + + 'this.innerWidth=function() {return this; };' + + 'this.insertAfter=function() {return this; };' + + 'this.insertBefore=function() {return this; };' + + 'this.is=function() {return this; };' + + 'this.jQuery=function() {return this; };' + + 'this.jquery=function() {return this; };' + + 'this.keydown=function() {return this; };' + + 'this.keypress=function() {return this; };' + + 'this.keyup=function() {return this; };' + + 'this.last=function() {return this; };' + + 'this.length=function() {return this; };' + + 'this.live=function() {return this; };' + + 'this.load=function() {return this; };' + + 'this.load=function() {return this; };' + + 'this.map=function() {return this; };' + + 'this.mousedown=function() {return this; };' + + 'this.mouseenter=function() {return this; };' + + 'this.mouseleave=function() {return this; };' + + 'this.mousemove=function() {return this; };' + + 'this.mouseout=function() {return this; };' + + 'this.mouseover=function() {return this; };' + + 'this.mouseup=function() {return this; };' + + 'this.next=function() {return this; };' + + 'this.nextAll=function() {return this; };' + + 'this.nextUntil=function() {return this; };' + + 'this.not=function() {return this; };' + + 'this.off=function() {return this; };' + + 'this.offset=function() {return this; };' + + 'this.offsetParent=function() {return this; };' + + 'this.on=function() {return this; };' + + 'this.one=function() {return this; };' + + 'this.outerHeight=function() {return this; };' + + 'this.outerWidth=function() {return this; };' + + 'this.parent=function() {return this; };' + + 'this.parents=function() {return this; };' + + 'this.parentsUntil=function() {return this; };' + + 'this.position=function() {return this; };' + + 'this.prepend=function() {return this; };' + + 'this.prependTo=function() {return this; };' + + 'this.prev=function() {return this; };' + + 'this.prevAll=function() {return this; };' + + 'this.prevUntil=function() {return this; };' + + 'this.promise=function() {return this; };' + + 'this.prop=function() {return this; };' + + 'this.pushStack=function() {return this; };' + + 'this.queue=function() {return this; };' + + 'this.ready=function() {return this; };' + + 'this.remove=function() {return this; };' + + 'this.removeAttr=function() {return this; };' + + 'this.removeClass=function() {return this; };' + + 'this.removeData=function() {return this; };' + + 'this.removeProp=function() {return this; };' + + 'this.replaceAll=function() {return this; };' + + 'this.replaceWith=function() {return this; };' + + 'this.resize=function() {return this; };' + + 'this.scroll=function() {return this; };' + + 'this.scrollLeft=function() {return this; };' + + 'this.scrollTop=function() {return this; };' + + 'this.select=function() {return this; };' + + 'this.selector=function() {return this; };' + + 'this.serialize=function() {return this; };' + + 'this.serializeArray=function() {return this; };' + + 'this.show=function() {return this; };' + + 'this.siblings=function() {return this; };' + + 'this.size=function() {return this; };' + + 'this.slice=function() {return this; };' + + 'this.slideDown=function() {return this; };' + + 'this.slideToggle=function() {return this; };' + + 'this.slideUp=function() {return this; };' + + 'this.stop=function() {return this; };' + + 'this.submit=function() {return this; };' + + 'this.text=function() {return this; };' + + 'this.toArray=function() {return this; };' + + 'this.toggle=function() {return this; };' + + 'this.toggle=function() {return this; };' + + 'this.toggleClass=function() {return this; };' + + 'this.trigger=function() {return this; };' + + 'this.triggerHandler=function() {return this; };' + + 'this.unbind=function() {return this; };' + + 'this.undelegate=function() {return this; };' + + 'this.unload=function() {return this; };' + + 'this.unwrap=function() {return this; };' + + 'this.val=function() {return this; };' + + 'this.width=function() {return this; };' + + 'this.wrap=function() {return this; };' + + 'this.wrapAll=function() {return this; };' + + 'this.wrapInner=function() {return this; };};};' + + '$.ajax=function() {return $;};' + + '$.ajaxPrefilter=function() {return $; };' + + '$.ajaxSetup=function() {return $; };' + + '$.ajaxTransport=function() {return $; };' + + '$.boxModel=function() {return $; };' + + '$.browser=function() {return $; };' + + '$.Callbacks=function() {return $; };' + + '$.contains=function() {return $; };' + + '$.cssHooks=function() {return $; };' + + '$.cssNumber=function() {return $; };' + + '$.data=function() {return $; };' + + '$.Deferred=function() {return $; };' + + '$.dequeue=function() {return $; };' + + '$.each=function() {return $; };' + + '$.error=function() {return $; };' + + '$.extend=function() {return $; };' + + '$.fnextend=function() {return $; };' + + '$.fxinterval=function() {return $; };' + + '$.fxoff=function() {return $; };' + + '$.get=function() {return $; };' + + '$.getJSON=function() {return $; };' + + '$.getScript=function() {return $; };' + + '$.globalEval=function() {return $; };' + + '$.grep=function() {return $; };' + + '$.hasData=function() {return $; };' + + '$.holdReady=function() {return $; };' + + '$.inArray=function() {return $; };' + + '$.isArray=function() {return $; };' + + '$.isEmptyObject=function() {return $; };' + + '$.isFunction=function() {return $; };' + + '$.isNumeric=function() {return $; };' + + '$.isPlainObject=function() {return $; };' + + '$.isWindow=function() {return $; };' + + '$.isXMLDoc=function() {return $; };' + + '$.makeArray=function() {return $; };' + + '$.map=function() {return $; };' + + '$.merge=function() {return $; };' + + '$.noConflict=function() {return $; };' + + '$.noop=function() {return $; };' + + '$.now=function() {return $; };' + + '$.param=function() {return $; };' + + '$.parseHTML=function() {return $; };' + + '$.parseJSON=function() {return $; };' + + '$.parseXML=function() {return $; };' + + '$.post=function() {return $; };' + + '$.proxy=function() {return $; };' + + '$.queue=function() {return $; };' + + '$.removeData=function() {return $; };' + + '$.sub=function() {return $; };' + + '$.support=function() {return $; };' + + '$.trim=function() {return $; };' + + '$.type=function() {return $; };' + + '$.unique=function() {return $; };' + + '$.when=function() {return $; };' + + '$.always=function() {return $; };' + + '$.done=function() {return $; };' + + '$.fail=function() {return $; };' + + '$.isRejected=function() {return $; };' + + '$.isResolved=function() {return $; };' + + '$.notify=function() {return $; };' + + '$.notifyWith=function() {return $; };' + + '$.pipe=function() {return $; };' + + '$.progress=function() {return $; };' + + '$.promise=function() {return $; };' + + '$.reject=function() {return $; };' + + '$.rejectWith=function() {return $; };' + + '$.resolve=function() {return $; };' + + '$.resolveWith=function() {return $; };' + + '$.state=function() {return $; };' + + '$.then=function() {return $; };' + + '$.currentTarget=function() {return $; };' + + '$.data=function() {return $; };' + + '$.delegateTarget=function() {return $; };' + + '$.isDefaultPrevented=function() {return $; };' + + '$.isImmediatePropagationStopped=function() {return $; };' + + '$.isPropagationStopped=function() {return $; };' + + '$.metaKey=function() {return $; };' + + '$.namespace=function() {return $; };' + + '$.pageX=function() {return $; };' + + '$.pageY=function() {return $; };' + + '$.preventDefault=function() {return $; };' + + '$.relatedTarget=function() {return $; };' + + '$.result=function() {return $; };' + + '$.stopImmediatePropagation=function() {return $; };' + + '$.stopPropagation=function() {return $; };' + + '$.target=function() {return $; };' + + '$.timeStamp=function() {return $; };' + + '$.type=function() {return $; };' + + '$.which=function() {return $; };' + + '' + s; // add spoofigator - s = " var navigator = " + - "function(){" + - " this.geolocation=function(){" + - " this.getCurrentPosition=function(){" + - " this.coords = {latitude: \"\", longitude: \"\"};" + - " return(this);" + - " };" + - " return(this);" + - " };" + - " return(this);" + - "};" + s; + s = ' var navigator = ' + + 'function() {' + + ' this.geolocation=function() {' + + ' this.getCurrentPosition=function() {' + + ' this.coords = {latitude: "", longitude: ""};' + + ' return this;' + + ' };' + + ' return this;' + + ' };' + + ' return this;' + + '};' + s; sandBox.submit(scopejQuery(s), function(cls, message) { if (cls) { @@ -582,14 +851,14 @@ function safeHTMLRun(test) { function updatePreview() { editorValueForIFrame = editor.getValue(); var failedCommentTest = false; + var openingComments = editorValueForIFrame.match(/\<\!\-\-/gi); + var closingComments = editorValueForIFrame.match(/\-\-\>/gi); if ( - editorValueForIFrame.match(/\<\!\-\-/gi) && - editorValueForIFrame.match(/\-\-\>/gi) == null - ) { - failedCommentTest = true; - } else if ( - editorValueForIFrame.match(/\<\!\-\-/gi) && - editorValueForIFrame.match(/\<\!\-\-/gi).length > editorValueForIFrame.match(/\-\-\>/gi).length + openingComments && + ( + !closingComments || + openingComments.length > closingComments.length + ) ) { failedCommentTest = true; } @@ -606,17 +875,8 @@ function updatePreview() { } } -if (typeof prodOrDev !== 'undefined') { - - /* eslint-disable no-unused-vars */ - var nodeEnv = window.prodOrDev === 'production' ? - 'http://www.freecodecamp.com' : - 'http://localhost:3001'; - /* eslint-enable no-unused-vars */ - - if (common.challengeType === '0') { - setTimeout(updatePreview, 300); - } +if (common.challengeType === '0') { + setTimeout(updatePreview, 300); } /** @@ -630,7 +890,9 @@ var postSuccess = function(data) { var testDoc = document.createElement('div'); $(testDoc).html( - "
" + + "
" + + "
" + + "
" + JSON.parse(data) + '
' ); @@ -639,11 +901,15 @@ var postSuccess = function(data) { testSuccess(); }; +/* eslint-disable no-unused-vars */ var postError = function(data) { +/* eslint-enable no-unused-vars */ var testDoc = document.createElement('div'); $(testDoc).html( - "
" + + "
" + + "
" + + "
" + JSON.parse(data) + '
' ); @@ -846,7 +1112,10 @@ var reassembleTest = function(test, data) { }; var runTests = function(err, data) { - var editorValue = editor.getValue(); + var head = common.arrayToNewLineString(common.head); + var tail = common.arrayToNewLineString(common.tail); + + var editorValue = head + editor.getValue() + tail; // userTests = userTests ? null : []; var allTestsPassed = true; pushed = false; @@ -1098,6 +1367,8 @@ common.init.push((function() { }(window.$))); function bonfireExecute(shouldTest) { + var head = common.arrayToNewLineString(common.head); + var tail = common.arrayToNewLineString(common.tail); var codeOutput = common.codeOutput; initPreview = false; goodTests = 0; @@ -1110,14 +1381,15 @@ function bonfireExecute(shouldTest) { common.challengeType !== '0' && !editor.getValue().match(/\$\s*?\(\s*?\$\s*?\)/gi) ) { - var userJavaScript = editor.getValue(); + var userJavaScript = head + editor.getValue() + tail; var failedCommentTest = false; + var openingComments = userJavaScript.match(/\/\*/gi); // checks if the number of opening comments(/*) matches the number of // closing comments(*/) if ( - userJavaScript.match(/\/\*/gi) && - userJavaScript.match(/\/\*/gi).length > userJavaScript.match(/\*\//gi).length + openingComments && + openingComments.length > userJavaScript.match(/\*\//gi).length ) { failedCommentTest = true; } @@ -1228,7 +1500,12 @@ $(document).ready(function() { bonfireExecute(true); } }); - } else if (common.challengeType !== 7) { + } else if ( + common.challengeType !== '2' && + common.challengeType !== '3' && + common.challengeType !== '4' && + common.challengeType !== '7' + ) { bonfireExecute(true); } diff --git a/client/iFrameScripts.js b/client/iFrameScripts.js index 1d5db5413d..61c4c66fe5 100644 --- a/client/iFrameScripts.js +++ b/client/iFrameScripts.js @@ -1,3 +1,4 @@ +/* eslint-disable no-undef, no-unused-vars, no-native-reassign */ (function() { var expect = chai.expect; var tests = parent.tests; @@ -7,7 +8,9 @@ for (var i = 0; i < tests.length; i++) { var thisTest = true; try { + /* eslint-disable no-eval */ eval(parent.tests[i]); + /* eslint-enable no-eval */ } catch (err) { allTestsGood = false; thisTest = false; diff --git a/client/less/main.less b/client/less/main.less index 12523d6991..1c41b9dd15 100644 --- a/client/less/main.less +++ b/client/less/main.less @@ -820,7 +820,8 @@ iframe.iphone { .news-box-search { @media (min-width: 768px) { - margin-top: -50px; + margin-top: -30px; + padding-bottom: 20px; } @media (max-width: 767px) { padding: 5px; diff --git a/client/main.js b/client/main.js index 6f147abcf7..b75297031e 100644 --- a/client/main.js +++ b/client/main.js @@ -4,6 +4,15 @@ main.mapShareKey = 'map-shares'; main.ga = window.ga || function() {}; +main.challengeTypes = { + 'HTML_CSS_JQ': '0', + 'JAVASCRIPT': '1', + 'VIDEO': '2', + 'ZIPLINE': '3', + 'BASEJUMP': '4', + 'BONFIRE': '5' +}; + main = (function(main) { // should be set before gitter script loads @@ -103,6 +112,44 @@ main = (function(main) { return main; }(main)); +main.lockTop = function lockTop() { + var magiVal; + + if ($(window).width() >= 990) { + if ($('.editorScrollDiv').html()) { + + magiVal = $(window).height() - + $('.navbar').height() + + $('.footer').height(); + + if (magiVal < 0) { + magiVal = 0; + } + $('.editorScrollDiv').css('height', magiVal - 85 + 'px'); + } + + magiVal = $(window).height() - + $('.navbar').height() + + $('.footer').height(); + + if (magiVal < 0) { + magiVal = 0; + } + + $('.scroll-locker') + .css('min-height', $('.editorScrollDiv').height()) + .css('height', magiVal - 185); + } else { + $('.editorScrollDiv').css('max-height', 500 + 'px'); + + $('.scroll-locker') + .css('position', 'inherit') + .css('top', 'inherit') + .css('width', '100%') + .css('max-height', '85%'); + } +}; + var lastCompleted = typeof lastCompleted !== 'undefined' ? lastCompleted : ''; @@ -143,11 +190,11 @@ $(document).ready(function() { ''; if (challengeName) { - ga('send', 'event', 'Challenge', 'load', challengeName); + ga('send', 'event', 'Challenge', 'load', challengeName); } if (typeof editor !== 'undefined') { - $('#reset-button').on('click', resetEditor); + $('#reset-button').on('click', window.resetEditor); } var CSRF_HEADER = 'X-CSRF-Token'; @@ -164,7 +211,7 @@ $(document).ready(function() { $('.checklist-element').each(function() { var checklistElementId = $(this).attr('id'); - if(!!localStorage[checklistElementId]) { + if (localStorage[checklistElementId]) { $(this).children().children('li').addClass('faded'); $(this).children().children('input').trigger('click'); } @@ -179,13 +226,14 @@ $(document).ready(function() { $('.challenge-list-checkbox').on('change', function() { var checkboxId = $(this).parent().parent().attr('id'); - if ($(this).is(":checked")) { + if ($(this).is(':checked')) { $(this).parent().siblings().children().addClass('faded'); if (!localStorage || !localStorage[checkboxId]) { localStorage[checkboxId] = true; } } - if (!$(this).is(":checked")) { + + if (!$(this).is(':checked')) { $(this).parent().siblings().children().removeClass('faded'); if (localStorage[checkboxId]) { localStorage.removeItem(checkboxId); @@ -193,217 +241,309 @@ $(document).ready(function() { } }); - $("img").error(function () { - $(this).unbind("error").attr("src", "https://s3.amazonaws.com/freecodecamp/camper-image-placeholder.png"); + $('img').error(function() { + $(this) + .unbind('error') + .attr( + 'src', + 'https://s3.amazonaws.com/freecodecamp/camper-image-placeholder.png' + ); }); - function reBindModals(){ + function reBindModals() { + if (!window.common) { + return; + } + var common = window.common; - $('.close-modal').unbind('click'); - $('.close-modal').on('click', function(){ - setTimeout(function() { - $('.close-modal').parent().parent().parent().parent().modal('hide'); - }, 200); - }); - - $('#search-issue').unbind('click'); - $('#search-issue').on('click', function() { - var queryIssue = window.location.href.toString(); - window.open('https://github.com/FreeCodeCamp/FreeCodeCamp/issues?q=' + - 'is:issue is:all ' + (challenge_Name || challengeName) + ' OR ' + - queryIssue.substr(queryIssue.lastIndexOf('challenges/') + 11) - .replace('/', ''), '_blank'); - }); - - $('#help-ive-found-a-bug-wiki-article').unbind('click'); - $('#help-ive-found-a-bug-wiki-article').on('click', function() { - window.open("https://github.com/FreeCodeCamp/FreeCodeCamp/wiki/Help-I've-Found-a-Bug", '_blank'); - }); - - $('#report-issue').unbind('click'); - $('#report-issue').on('click', function() { - var textMessage = [ - 'Challenge [', - (challenge_Name || challengeName || window.location.href), - '](', - window.location.href, - ') has an issue.\n', - 'User Agent is: ', - navigator.userAgent, - '.\n', - 'Please describe how to reproduce this issue, and include ', - 'links to screenshots if possible.\n\n' - ].join(''); - - if (typeof editor !== 'undefined' && editor.getValue().trim()) { - var type; - switch (challengeType) { - case challengeTypes.HTML_CSS_JQ: - type = 'html'; - break; - case challengeTypes.JAVASCRIPT: - case challengeTypes.BONFIRE: - type = 'javascript'; - break; - default: - type = ''; - } - - textMessage += [ - 'My code:\n```', - type, - '\n', - editor.getValue(), - '\n```\n\n' - ].join(''); - } - - textMessage = encodeURIComponent(textMessage); - - $('#issue-modal').modal('hide'); - window.open( - 'https://github.com/freecodecamp/freecodecamp/issues/new?&body=' + - textMessage, '_blank' - ); - }); - - $('#completed-courseware').unbind('click'); - $('#completed-courseware').on('click', function() { - $('#complete-courseware-dialog').modal('show'); - }); - - $('#completed-courseware-editorless').unbind('click'); - $('#completed-courseware-editorless').on('click', function() { - $('#complete-courseware-editorless-dialog').modal('show'); - }); - - $('#trigger-pair-modal').unbind('click'); - $('#trigger-pair-modal').on('click', function() { - $('#pair-modal').modal('show'); - }); - - $('#trigger-reset-modal').unbind('click'); - $('#trigger-reset-modal').on('click', function() { - $('#reset-modal').modal('show'); - }); - - $('#trigger-help-modal').unbind('click'); - $('#trigger-help-modal').on('click', function() { - $('#help-modal').modal('show'); - }); - - $('#trigger-issue-modal').unbind('click'); - $('#trigger-issue-modal').on('click', function() { - $('#issue-modal').modal('show'); - }); - - $('#completed-zipline-or-basejump').unbind('click'); - $('#completed-zipline-or-basejump').on('click', function() { - $('#complete-zipline-or-basejump-dialog').modal('show'); - }); - - $('#next-courseware-button').unbind('click'); - $('#next-courseware-button').on('click', function() { - $('#next-courseware-button').unbind('click'); - if ($('.signup-btn-nav').length < 1) { - switch (challengeType) { - case challengeTypes.HTML_CSS_JQ: - case challengeTypes.JAVASCRIPT: - case challengeTypes.VIDEO: - $.post( - '/completed-challenge/', - { - challengeInfo: { - challengeId: challenge_Id, - challengeName: challenge_Name - } - }).success( - function(res) { - if (res) { - window.location.href = '/challenges/next-challenge?id=' + challenge_Id; - } - }).fail( - function() { - window.location.href="/challenges"; - } - ); - break; - case challengeTypes.ZIPLINE: - var didCompleteWith = $('#completed-with').val() || null; - var publicURL = $('#public-url').val() || null; - $.post( - '/completed-zipline-or-basejump/', - { - challengeInfo: { - challengeId: challenge_Id, - challengeName: challenge_Name, - completedWith: didCompleteWith, - publicURL: publicURL, - challengeType: challengeType - } - }).success( - function() { - window.location.href = '/challenges/next-challenge?id=' + challenge_Id; - }).fail( - function() { - window.location.href = '/challenges'; - }); - break; - case challengeTypes.BASEJUMP: - var didCompleteWith = $('#completed-with').val() || null; - var publicURL = $('#public-url').val() || null; - var githubURL = $('#github-url').val() || null; - $.post( - '/completed-zipline-or-basejump/', - { - challengeInfo: { - challengeId: challenge_Id, - challengeName: challenge_Name, - completedWith: didCompleteWith, - publicURL: publicURL, - githubURL: githubURL, - challengeType: challengeType, - verified: false - } - }).success(function() { - window.location.href = '/challenges/next-challenge?id=' + challenge_Id; - }).fail(function() { - window.location.replace(window.location.href); - }); - break; - case challengeTypes.BONFIRE: - window.location.href = '/challenges/next-challenge?id=' + challenge_Id; - default: - break; - } - } - }); - - $('#complete-courseware-dialog').on('hidden.bs.modal', function() { - editor.focus(); - }); - - $('#complete-zipline-or-basejump').on('hidden.bs.modal', function() { - editor.focus(); - }); - }; - - - - $(window).resize(function(){ - reBindModals(); + $('.close-modal').unbind('click'); + $('.close-modal').on('click', function() { + setTimeout(function() { + $('.close-modal').parent().parent().parent().parent().modal('hide'); + }, 200); }); - reBindModals(); + $('#search-issue').unbind('click'); + $('#search-issue').on('click', function() { + var queryIssue = window.location.href.toString(); + window.open( + 'https://github.com/FreeCodeCamp/FreeCodeCamp/issues?q=' + + 'is:issue is:all ' + + (common.challengeName) + + ' OR ' + + queryIssue + .substr(queryIssue.lastIndexOf('challenges/') + 11) + .replace('/', ''), '_blank'); + }); - var challengeTypes = { - 'HTML_CSS_JQ': '0', - 'JAVASCRIPT': '1', - 'VIDEO': '2', - 'ZIPLINE': '3', - 'BASEJUMP': '4', - 'BONFIRE': '5' - }; + $('#gist-share').unbind('click'); + $('#gist-share').on('click', function() { + var gistWindow = window.open('', '_blank'); + + $('#gist-share') + .attr('disabled', 'true') + .removeClass('btn-danger') + .addClass('btn-warning disabled'); + + function createCORSRequest(method, url) { + var xhr = new XMLHttpRequest(); + if ('withCredentials' in xhr) { + xhr.open(method, url, true); + } else if (typeof XDomainRequest !== 'undefined') { + xhr = new XDomainRequest(); + xhr.open(method, url); + } else { + xhr = null; + } + xhr.setRequestHeader('Content-type', 'application/json; charset=utf-8'); + return xhr; + } + + var request = createCORSRequest('post', 'https://api.github.com/gists'); + if (!request) { + return null; + } + + request.onload = function() { + if ( + request.readyState === 4 && + request.status === 201 && + request.statusText === 'Created' + ) { + gistWindow.location.href = + JSON.parse(request.responseText)['html_url']; + } + }; + + var description = common.username ? + 'http://www.freecodecamp.com/' + common.username + ' \'s s' : + 'S'; + + var data = { + description: description + 'olution for ' + common.challengeName, + public: true, + files: {} + }; + var queryIssue = window.location.href.toString().split('#?')[0]; + var filename = queryIssue + .substr(queryIssue.lastIndexOf('challenges/') + 11) + .replace('/', '') + '.js'; + + data.files[filename] = { + content: '// ' + + common.challengeName + + '\n' + + (common.username ? '// Author: @' + common.username + '\n' : '') + + '// Challenge: ' + + queryIssue + + '\n' + + '// Learn to Code at Free Code Camp (www.freecodecamp.com)' + + '\n\n' + + window.editor.getValue().trim() + }; + + request.send(JSON.stringify(data)); + }); + + $('#help-ive-found-a-bug-wiki-article').unbind('click'); + $('#help-ive-found-a-bug-wiki-article').on('click', function() { + window.open( + 'https://github.com/FreeCodeCamp/FreeCodeCamp/wiki/' + + "Help-I've-Found-a-Bug", + '_blank' + ); + }); + + $('#report-issue').unbind('click'); + $('#report-issue').on('click', function() { + var textMessage = [ + 'Challenge [', + (common.challengeName || window.location.href), + '](', + window.location.href, + ') has an issue.\n', + 'User Agent is: ', + navigator.userAgent, + '.\n', + 'Please describe how to reproduce this issue, and include ', + 'links to screenshots if possible.\n\n' + ].join(''); + + if ( + window.editor && + typeof window.editor.getValue === 'function' && + window.editor.getValue().trim() + ) { + var type; + switch (common.challengeType) { + case main.challengeTypes.HTML_CSS_JQ: + type = 'html'; + break; + case main.challengeTypes.JAVASCRIPT: + case main.challengeTypes.BONFIRE: + type = 'javascript'; + break; + default: + type = ''; + } + + textMessage += [ + 'My code:\n```', + type, + '\n', + window.editor.getValue(), + '\n```\n\n' + ].join(''); + } + + textMessage = encodeURIComponent(textMessage); + + $('#issue-modal').modal('hide'); + window.open( + 'https://github.com/freecodecamp/freecodecamp/issues/new?&body=' + + textMessage, '_blank' + ); + }); + + $('#completed-courseware').unbind('click'); + $('#completed-courseware').on('click', function() { + $('#complete-courseware-dialog').modal('show'); + }); + + $('#completed-courseware-editorless').unbind('click'); + $('#completed-courseware-editorless').on('click', function() { + $('#complete-courseware-editorless-dialog').modal('show'); + }); + + $('#trigger-pair-modal').unbind('click'); + $('#trigger-pair-modal').on('click', function() { + $('#pair-modal').modal('show'); + }); + + $('#trigger-reset-modal').unbind('click'); + $('#trigger-reset-modal').on('click', function() { + $('#reset-modal').modal('show'); + }); + + $('#trigger-help-modal').unbind('click'); + $('#trigger-help-modal').on('click', function() { + $('#help-modal').modal('show'); + }); + + $('#trigger-issue-modal').unbind('click'); + $('#trigger-issue-modal').on('click', function() { + $('#issue-modal').modal('show'); + }); + + $('#completed-zipline-or-basejump').unbind('click'); + $('#completed-zipline-or-basejump').on('click', function() { + $('#complete-zipline-or-basejump-dialog').modal('show'); + }); + + $('#next-courseware-button').unbind('click'); + $('#next-courseware-button').on('click', function() { + $('#next-courseware-button').unbind('click'); + if ($('.signup-btn-nav').length < 1) { + var data; + var completedWith; + var publicURL; + switch (common.challengeType) { + case main.challengeTypes.HTML_CSS_JQ: + case main.challengeTypes.JAVASCRIPT: + case main.challengeTypes.VIDEO: + data = { + challengeInfo: { + challengeId: common.challengeId, + challengeName: common.challengeName + } + }; + $.post('/completed-challenge/', data) + .success(function(res) { + if (!res) { + return; + } + window.location.href = '/challenges/next-challenge?id=' + + common.challengeId; + }) + .fail(function() { + window.location.href = '/challenges'; + }); + + break; + case main.challengeTypes.ZIPLINE: + completedWith = $('#completed-with').val() || null; + publicURL = $('#public-url').val() || null; + data = { + challengeInfo: { + challengeId: common.challengeId, + challengeName: common.challengeName, + completedWith: completedWith, + publicURL: publicURL, + challengeType: common.challengeType + } + }; + + $.post('/completed-zipline-or-basejump/', data) + .success(function() { + window.location.href = '/challenges/next-challenge?id=' + + common.challengeId; + }) + .fail(function() { + window.location.href = '/challenges'; + }); + break; + + case main.challengeTypes.BASEJUMP: + completedWith = $('#completed-with').val() || null; + publicURL = $('#public-url').val() || null; + var githubURL = $('#github-url').val() || null; + data = { + challengeInfo: { + challengeId: common.challengeId, + challengeName: common.challengeName, + completedWith: completedWith, + publicURL: publicURL, + githubURL: githubURL, + challengeType: common.challengeType, + verified: false + } + }; + $.post('/completed-zipline-or-basejump/', data) + .success(function() { + window.location.href = '/challenges/next-challenge?id=' + + common.challengeId; + }) + .fail(function() { + window.location.replace(window.location.href); + }); + break; + + case main.challengeTypes.BONFIRE: + window.location.href = '/challenges/next-challenge?id=' + + common.challengeId; + break; + + default: + console.log('Happy Coding!'); + break; + } + } + }); + + $('#complete-courseware-dialog').on('hidden.bs.modal', function() { + window.editor.focus(); + }); + + $('#complete-zipline-or-basejump').on('hidden.bs.modal', function() { + window.editor.focus(); + }); + } + + $(window).resize(function() { + reBindModals(); + }); + + reBindModals(); function upvoteHandler(e) { e.preventDefault(); @@ -420,16 +560,19 @@ $(document).ready(function() { } if (!alreadyUpvoted) { $.post('/stories/upvote', { id: id }) - .fail(function(xhr, textStatus, errorThrown) { + .fail(function() { $(upvoteBtn).bind('click', upvoteHandler); }) - .done(function(data, textStatus, xhr) { - $(upvoteBtn).text('Upvoted!').addClass('disabled'); + .done(function(data) { + $(upvoteBtn) + .text('Upvoted!') + .addClass('disabled'); - $('#storyRank').text(data.rank + " points"); + $('#storyRank').text(data.rank + ' points'); }); } - }; + } + $('#story-list').on('click', 'button.btn-upvote', upvoteHandler); var storySubmitButtonHandler = function storySubmitButtonHandler() { @@ -437,92 +580,122 @@ $(document).ready(function() { var link = $('#story-url').val(); var headline = $('#story-title').val(); var description = $('#description-box').val(); + var data = { + data: { + link: link, + headline: headline, + timePosted: Date.now(), + description: description, + storyMetaDescription: main.storyMetaDescription, + rank: 1, + image: main.storyImage + } + }; $('#story-submit').unbind('click'); - $.post('/stories/', - { - data: { - link: link, - headline: headline, - timePosted: Date.now(), - description: description, - storyMetaDescription: storyMetaDescription, - rank: 1, - image: storyImage - } - }) - .fail(function (xhr, textStatus, errorThrown) { + $.post('/stories/', data) + .fail(function() { $('#story-submit').bind('click', storySubmitButtonHandler); }) - .done(function(data, textStatus, xhr) { + .done(function(data) { window.location = '/stories/' + data.storyLink; }); }; $('#story-submit').on('click', storySubmitButtonHandler); - //fakeiphone positioning hotfix - if($('.iphone-position').html() !==undefined || $('.iphone').html() !== undefined){ - var startIphonePosition = parseInt($('.iphone-position').css('top').replace('px', '')); - var startIphone = parseInt($('.iphone').css('top').replace('px', '')); - $(window).on('scroll', function(){ - if((($('.courseware-height').height() + $('.courseware-height').offset().top)-$(window).scrollTop()-$('.iphone-position').height()) <= 0){ - $('.iphone-position').css('top', startIphonePosition+(($('.courseware-height').height() + $('.courseware-height').offset().top)-$(window).scrollTop()-$('.iphone-position').height())); - $('.iphone').css('top', startIphonePosition+(($('.courseware-height').height() + $('.courseware-height').offset().top)-$(window).scrollTop()-$('.iphone-position').height())+120); - } - else{ - $('.iphone-position').css('top', startIphonePosition); - $('.iphone').css('top', startIphone); - } - }); - } - if($('.scroll-locker').html() != undefined){ - function lockTop(){ - if ($(window).width() >= 990) { - if($('.editorScrollDiv').html() !== 'undefined'){ - var magiVal = $(window).height()-($('.navbar').height()+$('.footer').height()); - if(magiVal < 0){ - magiVal = 0; - } - $('.editorScrollDiv').css("height", (magiVal-85) + "px"); - } - magiVal = $(window).height()-($('.navbar').height()+$('.footer').height()); - if(magiVal < 0){ - magiVal = 0; - } - $('.scroll-locker').css("min-height", $('.editorScrollDiv').height()).css("height",magiVal-185); - } - else { - $('.editorScrollDiv').css("max-height", 500 + "px"); - $('.scroll-locker').css('position', 'inherit').css('top', 'inherit').css('width', '100%').css('max-height', '85%'); - } - } - if ($('.scroll-locker').html()){ - lockTop(); - $(window).on('resize', function(){ - lockTop(); - }); - $(window).on('scroll', function() { - lockTop(); - }); - } - var execInProgress = false; - document.getElementById('scroll-locker').addEventListener('previewUpdateSpy', function(e){ - if (!execInProgress){ - execInProgress = true; - setTimeout(function(){ - if($($('.scroll-locker').children()[0]).height()-800 > e.detail){ - $('.scroll-locker').scrollTop(e.detail); - } - else { - $('.scroll-locker').animate({"scrollTop":$($('.scroll-locker').children()[0]).height()}, 175); - } - execInProgress = false; - }, 750); - } - }, false); + // fakeiphone positioning hotfix + if ( + $('.iphone-position').html() || + $('.iphone').html() + ) { + var startIphonePosition = parseInt( + $('.iphone-position') + .css('top') + .replace('px', ''), + 10 + ); + + var startIphone = parseInt( + $('.iphone') + .css('top') + .replace('px', ''), + 10 + ); + + $(window).on('scroll', function() { + var courseHeight = $('.courseware-height').height(); + var courseTop = $('.courseware-height').offset().top; + var windowScrollTop = $(window).scrollTop(); + var phoneHeight = $('.iphone-position').height(); + + if (courseHeight + courseTop - windowScrollTop - phoneHeight <= 0) { + $('.iphone-position').css( + 'top', + startIphonePosition + + courseHeight + + courseTop - + windowScrollTop - + phoneHeight + ); + + $('.iphone').css( + 'top', + startIphonePosition + + courseHeight + + courseTop - + windowScrollTop - + phoneHeight + + 120 + ); + } else { + $('.iphone-position').css('top', startIphonePosition); + $('.iphone').css('top', startIphone); + } + }); + } + + if ($('.scroll-locker').html()) { + + if ($('.scroll-locker').html()) { + main.lockTop(); + $(window).on('resize', function() { + main.lockTop(); + }); + $(window).on('scroll', function() { + main.lockTop(); + }); } + var execInProgress = false; + + // why is this not $??? + document + .getElementById('scroll-locker') + .addEventListener( + 'previewUpdateSpy', + function(e) { + if (execInProgress) { + return null; + } + execInProgress = true; + setTimeout(function() { + if ( + $($('.scroll-locker').children()[0]).height() - 800 > e.detail + ) { + $('.scroll-locker').scrollTop(e.detail); + } else { + var scrollTop = $($('.scroll-locker').children()[0]).height(); + + $('.scroll-locker').animate({ scrollTop: scrollTop }, 175); + } + execInProgress = false; + }, 750); + }, + false + ); + } + // map sharing var alreadyShared = getMapShares(); @@ -559,141 +732,153 @@ $(document).ready(function() { }); }); -function defCheck(a){ - if(a !== 'undefined'){return(true);}else{return(false);} -} +var profileValidation = + window.angular.module('profileValidation', ['ui.bootstrap']); -var profileValidation = angular.module('profileValidation', - ['ui.bootstrap']); -profileValidation.controller('profileValidationController', ['$scope', '$http', - function($scope, $http) { - $http.get('/account/api').success(function(data) { - $scope.user = data.user; - $scope.user.username = $scope.user.username ? $scope.user.username.toLowerCase() : undefined; - $scope.storedUsername = data.user.username; - $scope.storedEmail = data.user.email; - $scope.user.email = $scope.user.email ? $scope.user.email.toLowerCase() : undefined; - $scope.user.twitterHandle = $scope.user.twitterHandle ? $scope.user.twitterHandle.toLowerCase() : undefined; - $scope.asyncComplete = true; - }); - } -]); +profileValidation.controller( + 'profileValidationController', + [ + '$scope', + '$http', + function($scope, $http) { + $http.get('/account/api').success(function(data) { + $scope.user = data.user; -profileValidation.controller('pairedWithController', ['$scope', - function($scope) { - $scope.existingUser = null; - } -]); + $scope.user.username = $scope.user.username ? + $scope.user.username.toLowerCase() : + null; -profileValidation.controller('emailSignUpController', ['$scope', - function($scope) { + $scope.storedUsername = data.user.username; + $scope.storedEmail = data.user.email; + $scope.user.email = $scope.user.email ? + $scope.user.email.toLowerCase() : + null; - } -]); + $scope.user.twitterHandle = $scope.user.twitterHandle ? + $scope.user.twitterHandle.toLowerCase() : + null; -profileValidation.controller('emailSignInController', ['$scope', - function($scope) { - - } -]); - -profileValidation.controller('URLSubmitController', ['$scope', - function($scope) { - - } -]); - -profileValidation.controller('nonprofitFormController', ['$scope', - function($scope) { - - } -]); - -profileValidation.controller('doneWithFirst100HoursFormController', ['$scope', - function($scope) { - - } -]); - -profileValidation.controller('submitStoryController', ['$scope', - function($scope) { - - } -]); - -profileValidation.directive('uniqueUsername', ['$http', function($http) { - return { - restrict: 'A', - require: 'ngModel', - link: function (scope, element, attrs, ngModel) { - element.bind("keyup", function (event) { - ngModel.$setValidity('unique', true); - var username = element.val(); - if (username) { - var config = { params: { username: username } }; - $http - .get('/api/users/exists', config) - .success(function (result) { - if (username === scope.storedUsername) { - ngModel.$setValidity('unique', true); - } else if (result.exists) { - ngModel.$setValidity('unique', false); - } - }); - } + $scope.asyncComplete = true; }); } - }; -}]); + ] +); + +profileValidation.controller( + 'pairedWithController', + [ + '$scope', + function($scope) { $scope.existingUser = null; } + ] +); + +profileValidation.controller('emailSignUpController', function() {}); + +profileValidation.controller('emailSignInController', function() {}); + +profileValidation.controller('URLSubmitController', function() {}); + +profileValidation.controller('nonprofitFormController', function() {}); + +profileValidation.controller( + 'doneWithFirst100HoursFormController', + function() {} +); + +profileValidation.controller('submitStoryController', function() {}); + +profileValidation.directive( + 'uniqueUsername', + [ + '$http', + function($http) { + return { + restrict: 'A', + require: 'ngModel', + link: function(scope, element, attrs, ngModel) { + + element.bind('keyup', function() { + + ngModel.$setValidity('unique', true); + var username = element.val(); + if (username) { + var config = { params: { username: username } }; + $http + .get('/api/users/exists', config) + .success(function(result) { + if (username === scope.storedUsername) { + ngModel.$setValidity('unique', true); + } else if (result.exists) { + ngModel.$setValidity('unique', false); + } + }); + } + }); + } + }; + } + ] +); profileValidation.directive('existingUsername', - ['$http', function($http) { - return { - restrict: 'A', - require: 'ngModel', - link: function (scope, element, attrs, ngModel) { - element.bind('keyup', function (event) { - if (element.val().length > 0) { - ngModel.$setValidity('exists', false); - } else { - element.removeClass('ng-dirty'); - ngModel.$setPristine(); - } - var username = element.val(); - if (username) { - var config = { params: { username: username } }; - $http - .get('/api/users/exists', config) - .success(function(result) { - ngModel.$setValidity('exists', result.exists); - }); - } - }); - } - }; + [ + '$http', + function($http) { + return { + restrict: 'A', + require: 'ngModel', + link: function(scope, element, attrs, ngModel) { + + element.bind('keyup', function() { + + if (element.val().length > 0) { + ngModel.$setValidity('exists', false); + } else { + element.removeClass('ng-dirty'); + ngModel.$setPristine(); + } + + var username = element.val(); + if (username) { + var config = { params: { username: username } }; + $http + .get('/api/users/exists', config) + .success(function(result) { + ngModel.$setValidity('exists', result.exists); + }); + } + }); + } + }; }]); -profileValidation.directive('uniqueEmail', ['$http', function($http) { - return { - restrict: 'A', - require: 'ngModel', - link: function getUnique (scope, element, attrs, ngModel) { - element.bind("keyup", function (event) { - ngModel.$setValidity('unique', true); - var email = element.val(); - if (email) { - var config = { params: { email: email } }; - $http - .get('/api/users/exists', config) - .success(function(result) { - if (email === scope.storedEmail) { - ngModel.$setValidity('unique', true); - } else if (result.exists) { - ngModel.$setValidity('unique', false); - } - }); - }; - }); +profileValidation.directive( + 'uniqueEmail', + [ + '$http', + function($http) { + return { + restrict: 'A', + require: 'ngModel', + link: function getUnique(scope, element, attrs, ngModel) { + element.bind('keyup', function() { + ngModel.$setValidity('unique', true); + var email = element.val(); + if (email) { + var config = { params: { email: email } }; + $http + .get('/api/users/exists', config) + .success(function(result) { + if (email === scope.storedEmail) { + ngModel.$setValidity('unique', true); + } else if (result.exists) { + ngModel.$setValidity('unique', false); + } + }); + } + }); + } + }; } - } -}]); + ] +); diff --git a/client/plugin.js b/client/plugin.js index 36f869db1a..f53d68c71a 100644 --- a/client/plugin.js +++ b/client/plugin.js @@ -23,7 +23,7 @@ function run(code) { var codeExec = runHidden(code); result.type = typeof codeExec; result.output = stringify(codeExec); - } catch(e) { + } catch (e) { result.error = e.message; } diff --git a/common/app/components/Flash/Queue.jsx b/common/app/components/Flash/Queue.jsx index 718733a923..ac36ca3f46 100644 --- a/common/app/components/Flash/Queue.jsx +++ b/common/app/components/Flash/Queue.jsx @@ -1,7 +1,7 @@ -import React, { createClass, PropTypes } from 'react'; +import React, { PropTypes } from 'react'; import { Alert } from 'react-bootstrap'; -export default createClass({ +export default React.createClass({ displayName: 'FlashQueue', propTypes: { @@ -9,9 +9,9 @@ export default createClass({ }, renderMessages(messages) { - return messages.map(message => { + return messages.map(() => { return ( - + ); }); }, diff --git a/common/app/components/Nav/Nav.jsx b/common/app/components/Nav/Nav.jsx index b4a64fe6f6..37ff15817d 100644 --- a/common/app/components/Nav/Nav.jsx +++ b/common/app/components/Nav/Nav.jsx @@ -4,6 +4,7 @@ import { Col, CollapsibleNav, Nav, + NavBrand, Navbar, NavItem } from 'react-bootstrap'; @@ -107,11 +108,11 @@ export default React.createClass({ const { username, points, picture } = this.props; return ( + { logoElement }