diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2652680008..31070300e4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -251,7 +251,7 @@ and ensure all tests pass. ### Squash Your Commits When you make a pull request, all of your changes need to be in one commit. -If you have made more then one commit, then you will need to _squash_ your commits. +If you have made more than one commit, then you will need to _squash_ your commits. To do this, see [Squashing Your Commits](http://forum.freecodecamp.com/t/how-to-squash-multiple-commits-into-one-with-git/13231). @@ -271,7 +271,7 @@ related issues in our [Contributors chat room](https://gitter.im/FreeCodeCamp/Co #### Important: ALWAYS EDIT ON A BRANCH -Take away only one thing from this document, it should be this: Never, **EVER** +Take away only one thing from this document: Never, **EVER** make edits to the `staging` branch. ALWAYS make a new branch BEFORE you edit files. This is critical, because if your PR is not accepted, your copy of staging will be forever sullied and the only way to fix it is to delete your @@ -357,7 +357,7 @@ for further information 5. In the body of your PR include a more detailed summary of the changes you made and why. - - If the PR is meant to fix an existing bug/issue, then, at the end of + - If the PR is meant to fix an existing bug/issue then, at the end of your PR's description, append the keyword `closes` and #xxxx (where xxxx is the issue number). Example: `closes #1337`. This tells GitHub to close the existing issue, if the PR is merged. diff --git a/client/less/lib/bootstrap/modals.less b/client/less/lib/bootstrap/modals.less index 7468b14f97..3671ff0715 100755 --- a/client/less/lib/bootstrap/modals.less +++ b/client/less/lib/bootstrap/modals.less @@ -67,6 +67,7 @@ right: 0; bottom: 0; left: 0; + z-index: 1030; background-color: @modal-backdrop-bg; // Fade for backdrop &.fade { .opacity(0); } diff --git a/client/less/lib/bootstrap/variables.less b/client/less/lib/bootstrap/variables.less index 4498534de0..d9e5a316fe 100755 --- a/client/less/lib/bootstrap/variables.less +++ b/client/less/lib/bootstrap/variables.less @@ -41,7 +41,7 @@ //## Night mode styles @night-body-bg: @gray-dark; -@night-text-color: #999; +@night-text-color: #ccc; //== Typography // diff --git a/client/less/main.less b/client/less/main.less index 683ccae15e..6fe8878945 100644 --- a/client/less/main.less +++ b/client/less/main.less @@ -1088,7 +1088,7 @@ code { } } a, .input-group-addon, .challenge-instructions a, .challenge-instructions #MDN-links a { - color: #CCC; + color: #f8f8f8; } .fa-github-square { color: @brand-primary; diff --git a/client/rechallenge/throwers.js b/client/rechallenge/throwers.js index d2e4b62dfc..b8a7a38c20 100644 --- a/client/rechallenge/throwers.js +++ b/client/rechallenge/throwers.js @@ -49,13 +49,13 @@ const throwForJsHtml = { } } }, { - name: 'gomix in code', - description: 'Code with the URL gomix.me ' + + name: 'glitch in code', + description: 'Code with the URL glitch.com or glitch.me' + 'should not be allowed to run', - detectGomixInCode: /gomix\.me/gi, - thrower: function checkForGomix({ contents }) { - if (contents.match(this.detectGomixInCode)) { - throw new Error('Gomix.me should not be in the code'); + detectGlitchInCode: /glitch\.(com|me)/gi, + thrower: function checkForGlitch({ contents }) { + if (contents.match(this.detectGlitchInCode)) { + throw new Error('Glitch.com or Glitch.me should not be in the code'); } } } diff --git a/common/app/routes/challenges/views/classic/classic.less b/common/app/routes/challenges/views/classic/classic.less index e8dde73d7a..df8588a914 100644 --- a/common/app/routes/challenges/views/classic/classic.less +++ b/common/app/routes/challenges/views/classic/classic.less @@ -5,13 +5,13 @@ .max-element-height(up-to) { max-height: e(%('calc(100vh - %s)', @navbar-total-height)); overflow-x: hidden; - overflow-y: scroll; + overflow-y: auto; } .max-element-height(always) { height: e(%('calc(100vh - %s)', @navbar-total-height)); overflow-x: hidden; - overflow-y: scroll; + overflow-y: auto; } .@{ns}-instructions-panel { diff --git a/gulpfile.js b/gulpfile.js index 0ba252325f..8fdc688c09 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,9 +1,10 @@ // enable debug for gulp +/* eslint-disable prefer-object-spread/prefer-object-spread */ process.env.DEBUG = process.env.DEBUG || 'fcc:*'; require('dotenv').load(); require('babel-core/register'); -var Rx = require('rx'), +const Rx = require('rx'), gulp = require('gulp'), path = require('path'), debug = require('debug')('fcc:gulp'), @@ -50,19 +51,28 @@ var Rx = require('rx'), tapSpec = require('tap-spec'); Rx.config.longStackSupport = true; -var sync = browserSync.create('fcc-sync-server'); +const sync = browserSync.create('fcc-sync-server'); + +function resolve(filepath, thisString, withThisString) { + const newPath = require.resolve(filepath); + if (thisString && withThisString) { + return newPath.replace(thisString, withThisString); + } + return newPath; +} // user definable -var __DEV__ = !yargs.argv.p; -var host = process.env.HOST || 'localhost'; -var port = yargs.argv.port || process.env.PORT || '3001'; -var syncPort = yargs.argv['sync-port'] || process.env.SYNC_PORT || '3000'; +const __DEV__ = !yargs.argv.p; +const host = process.env.HOST || 'localhost'; +const port = yargs.argv.port || process.env.PORT || '3001'; +const syncPort = yargs.argv['sync-port'] || process.env.SYNC_PORT || '3000'; + // make sure sync ui port does not interfere with proxy port -var syncUIPort = yargs.argv['sync-ui-port'] || +const syncUIPort = yargs.argv['sync-ui-port'] || process.env.SYNC_UI_PORT || parseInt(syncPort, 10) + 2; -var paths = { +const paths = { server: './server/server.js', serverIgnore: [ 'gulpfile.js', @@ -89,32 +99,36 @@ var paths = { }, vendorChallenges: [ - require.resolve('jshint').replace('src', 'dist'), - require.resolve('chai').replace('index.js', 'chai.js'), - require.resolve('codemirror'), - require.resolve('codemirror').replace('lib/codemirror.js', 'addon/comment/comment.js'), - require.resolve('codemirror').replace('lib/codemirror.js', 'addon/edit/closebrackets.js'), - require.resolve('codemirror').replace('lib/codemirror.js', 'addon/edit/matchbrackets.js'), - require.resolve('codemirror').replace('lib/codemirror.js', 'addon/lint/lint.js'), - require.resolve('codemirror').replace('lib/codemirror.js', 'addon/lint/javascript-lint.js'), - require.resolve('codemirror').replace('lib/codemirror.js', 'mode/javascript/javascript.js'), - require.resolve('codemirror').replace('lib/codemirror.js', 'mode/xml/xml.js'), - require.resolve('codemirror').replace('lib/codemirror.js', 'mode/css/css.js'), - require.resolve('codemirror').replace('lib/codemirror.js', 'mode/htmlmixed/htmlmixed.js'), - require.resolve('emmet-codemirror'), + resolve('jshint', 'src', 'dist'), + resolve('chai', 'index.js', 'chai.js'), + resolve('codemirror'), + resolve('codemirror', 'lib/codemirror.js', 'addon/comment/comment.js'), + resolve('codemirror', 'lib/codemirror.js', 'addon/edit/closebrackets.js'), + resolve('codemirror', 'lib/codemirror.js', 'addon/edit/matchbrackets.js'), + resolve('codemirror', 'lib/codemirror.js', 'addon/lint/lint.js'), + resolve('codemirror', 'lib/codemirror.js', 'addon/lint/javascript-lint.js'), + resolve('codemirror', 'lib/codemirror.js', 'mode/javascript/javascript.js'), + resolve('codemirror', 'lib/codemirror.js', 'mode/xml/xml.js'), + resolve('codemirror', 'lib/codemirror.js', 'mode/css/css.js'), + resolve('codemirror', 'lib/codemirror.js', 'mode/htmlmixed/htmlmixed.js'), + resolve('emmet-codemirror'), 'public/js/lib/loop-protect/loop-protect.js' ], vendorMain: [ - require.resolve('jquery').replace('.js', '.min.js'), - require.resolve('bootstrap').replace('npm.js', 'bootstrap.min.js'), - require.resolve('d3').replace('.js', '.min.js'), - require.resolve('cal-heatmap'), - require.resolve('moment').replace('.js', '.min.js'), - require.resolve('moment-timezone').replace('index.js', 'builds/moment-timezone-with-data.min.js'), - require.resolve('mousetrap').replace('.js', '.min.js'), - require.resolve('lightbox2').replace('.js', '.min.js'), - require.resolve('rx').replace('index.js', 'dist/rx.all.min.js') + resolve('jquery', '.js', '.min.js'), + resolve('bootstrap', 'npm.js', 'bootstrap.min.js'), + resolve('d3', '.js', '.min.js'), + resolve('cal-heatmap'), + resolve('moment', '.js', '.min.js'), + resolve( + 'moment-timezone', + 'index.js', + 'builds/moment-timezone-with-data.min.js' + ), + resolve('mousetrap', '.js', '.min.js'), + resolve('lightbox2', '.js', '.min.js'), + resolve('rx', 'index.js', 'dist/rx.all.min.js') ], js: [ @@ -145,19 +159,18 @@ var paths = { ] }; -var webpackOptions = { +const webpackOptions = { devtool: 'inline-source-map' }; -function errorHandler() { - var args = Array.prototype.slice.call(arguments); +const errorNotifier = notify.onError({ + title: 'Compile Error', + message: '<%= error %>' +}); +function errorHandler(...args) { // Send error to notification center with gulp-notify - notify.onError({ - title: 'Compile Error', - message: '<%= error %>' - }).apply(this, args); - + errorNotifier.apply(this, args); // Keep gulp from hanging on this task this.emit('end'); } @@ -174,7 +187,7 @@ function delRev(dest, manifestName) { } gulp.task('serve', function(cb) { - var called = false; + let called = false; nodemon({ script: paths.server, ext: '.jsx .js .json', @@ -199,7 +212,7 @@ gulp.task('serve', function(cb) { }); }); -var syncDepenedents = [ +const syncDepenedents = [ 'serve', 'js', 'less' @@ -211,7 +224,7 @@ gulp.task('dev-server', syncDepenedents, function() { 'webpack-hot-middleware/client' ].concat(webpackConfig.entry.bundle); - var bundler = webpack(webpackConfig); + const bundler = webpack(webpackConfig); sync.init(null, { ui: { port: syncUIPort @@ -261,14 +274,14 @@ gulp.task('pack-client', function() { if (!__DEV__) { console.log('\n\nbundling production\n\n'); } function condition(file) { - var filepath = file.relative; + const filepath = file.relative; return __DEV__ || (/json$/).test('' + filepath); } - var dest = webpackConfig.output.path; + const dest = webpackConfig.output.path; return gulp.src(webpackConfig.entry.bundle) - .pipe(plumber({ errorHandler: errorHandler })) + .pipe(plumber({ errorHandler })) .pipe(webpackStream(Object.assign( {}, webpackConfig, @@ -278,15 +291,15 @@ gulp.task('pack-client', function() { .pipe(gulp.dest(dest)); }); -var webpackManifestFiles = [ 'react-manifest.json', 'chunk-manifest.json' ]; +const webpackManifestFiles = [ 'react-manifest.json', 'chunk-manifest.json' ]; gulp.task('move-webpack-manifest', ['pack-client'], function() { - var files = webpackManifestFiles.map(function(filename) { + const files = webpackManifestFiles.map(function(filename) { return path.join(webpackConfig.output.path, filename); }); return gulp.src(files).pipe(gulp.dest(paths.manifest)); }); -var cleanDeps = ['pack-client', 'move-webpack-manifest']; +const cleanDeps = ['pack-client', 'move-webpack-manifest']; gulp.task('clean-webpack-manifest', cleanDeps, function() { return del(webpackManifestFiles.map(function(filename) { return path.join(webpackConfig.output.path, filename); @@ -300,10 +313,10 @@ gulp.task('clean-webpack-manifest', cleanDeps, function() { }); gulp.task('less', function() { - var manifestName = 'css-manifest.json'; - var dest = paths.css; + const manifestName = 'css-manifest.json'; + const dest = paths.css; return gulp.src(paths.less) - .pipe(plumber({ errorHandler: errorHandler })) + .pipe(plumber({ errorHandler })) .pipe(__DEV__ ? sourcemaps.init() : gutil.noop()) // compile .pipe(less({ @@ -343,10 +356,10 @@ function getFilesGlob(files) { } gulp.task('js', function() { - var manifestName = 'js-manifest.json'; - var dest = paths.publicJs; + const manifestName = 'js-manifest.json'; + const dest = paths.publicJs; - var jsFiles = merge( + const jsFiles = merge( gulp.src(getFilesGlob(paths.vendorMain)) .pipe(__DEV__ ? sourcemaps.init() : gutil.noop()) @@ -368,7 +381,7 @@ gulp.task('js', function() { ), gulp.src(paths.js) - .pipe(plumber({ errorHandler: errorHandler })) + .pipe(plumber({ errorHandler })) .pipe(babel()) .pipe(__DEV__ ? gutil.noop() : uglify()) ); @@ -398,7 +411,7 @@ function done(manifest) { return sortKeys(manifest); } -var buildDependents = [ +const buildDependents = [ 'less', 'js', 'pack-client', @@ -420,7 +433,7 @@ gulp.task('build', [ 'build-manifest' ]); -var watchDependents = [ +const watchDependents = [ 'less', 'js', 'serve', diff --git a/package.json b/package.json index 0c9d3deeb1..7c5a67b3fd 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "lint-resources": "jsonlint-cli server/resources/*.json", "lint-utils": "jsonlint-cli server/utils/*.json", "prelint-js": "npm run create-rev", - "lint-js": "eslint --ext=.js,.jsx server/ common/ config/ client/", + "lint-js": "eslint --ext=.js,.jsx gulpfile.js server/ common/ config/ client/", "lint-json": "npm run lint-server && npm run lint-challenges && npm run lint-resources && npm run lint-utils", "pretest": "npm run create-rev && npm run lint", "snyk-protect": "snyk protect", diff --git a/seed/challenges/00-getting-started/getting-started.json b/seed/challenges/00-getting-started/getting-started.json index e8837fb345..f7c5e87a74 100644 --- a/seed/challenges/00-getting-started/getting-started.json +++ b/seed/challenges/00-getting-started/getting-started.json @@ -658,7 +658,7 @@ [ "//i.imgur.com/OmRmLB4.gif", "A gif showing you how to click the link below to go to our chat room and click the \"sign in with GitHub\" button. Then you can click into the text input field and type a message to your fellow campers.", - "Now that you have a GitHub account, you can join our main chat room by logging in with GitHub. Introduce yourself by saying \"Hello world!\" Tell your fellow campers how you found freeCodeCamp. Also tell us why you want to learn to code.", + "Now that you have a GitHub account, you can join our main chat room by logging in with GitHub. Please do not sign in with Twitter. Introduce yourself by saying \"Hello world!\" Tell your fellow campers how you found freeCodeCamp. Also tell us why you want to learn to code.", "https://gitter.im/FreeCodeCamp/FreeCodeCamp" ], [ @@ -721,7 +721,7 @@ [ "//i.imgur.com/OmRmLB4.gif", "Ein GIF das dir zeigt wie der unten stehende Link geklickt, auf den Chat weitergeleitet und mit dem \"Melde dich mit GitHub an\" Button man angemeldet wird. Dann kannst du auf das Textfeld klicken und eine Nachricht an andere Camper schicken", - "Jetzt, da du einen GitHub Account besitzt, kannst du unserem Hauptchat beitreten indem du dich mit GitHub anmeldest. Stell dich vor indem du \"Hello World\" schreibst. Erzähl den anderen Campern wie du freeCodeCamp gefunden hast. Außerdem könntest du uns erzählen warum du programmieren lernen willst.", + "Jetzt, da du einen GitHub Account besitzt, kannst du unserem Hauptchat beitreten indem du dich mit GitHub anmeldest. Bitte melde dich nicht mit Twitter an. Stell dich vor indem du \"Hello World\" schreibst. Erzähl den anderen Campern wie du freeCodeCamp gefunden hast. Außerdem könntest du uns erzählen warum du programmieren lernen willst.", "https://gitter.im/FreeCodeCamp/FreeCodeCamp" ], [ @@ -781,7 +781,7 @@ [ "//i.imgur.com/OmRmLB4.gif", "Un gif mostrándote como pulsar en el enlace inferior para ir a nuestra sala de chat y pulsar en el botón de \"iniciar sesión con GitHub\". Entonces puedes pulsar en el próximo campo de texto y escribir un mensaje a tus compañeros campistas.", - "Ahora que tienes una cuenta de GitHub, puedes unirte a nuestro chat principal al iniciar sesión con GitHub. Preséntate diciendo \"Hello world!\" Cuéntales a los tus compañeros campistas como encontraste freeCodeCamp. Además cuéntanos porque deseas aprender a programar.", + "Ahora que tienes una cuenta de GitHub, puedes unirte a nuestro chat principal al iniciar sesión con GitHub. Por favor no ingrese con Twitter. Preséntate diciendo \"Hello world!\" Cuéntales a los tus compañeros campistas como encontraste freeCodeCamp. Además cuéntanos porque deseas aprender a programar.", "https://gitter.im/FreeCodeCamp/FreeCodeCamp" ], [ @@ -840,7 +840,7 @@ [ "//i.imgur.com/OmRmLB4.gif", "Un gif vous montrant comment Cliquez sur le lien ci-dessous pour accéder à notre salle de chat et cliquez sur \"Se connecter avec\" bouton GitHub. Puis vous pouvez cliquer dans le champ de saisie de texte et saisissez un message à vos amis campeurs.", - "Maintenant que vous avez une GitHub compte, vous pouvez vous joindre à notre principale salle de chat en vous connectant à GitHub. Présentez-vous en disant \"Hello World!\" avertissez votre amis campeurs comment vous avez trouvé Libre Code Camp. Aussi nous dire pourquoi vous voulez apprendre à code.", + "Maintenant que vous avez une GitHub compte, vous pouvez vous joindre à notre principale salle de chat en vous connectant à GitHub. Ne connectez-vous pas avec Twitter. Présentez-vous en disant \"Hello World!\" avertissez votre amis campeurs comment vous avez trouvé Libre Code Camp. Aussi nous dire pourquoi vous voulez apprendre à code.", "https://gitter.im/FreeCodeCamp/FreeCodeCamp" ], [ @@ -899,7 +899,7 @@ [ "//i.imgur.com/OmRmLB4.gif", "Una gif che mostra come cliccare sul link qui sotto per andare alla nostra chat room e fare clic sul pulsante \" accedi con GitHub \". Quindi potrai cliccare nel campo di immissione testo e digitare un messaggio agli altri campers.", - "Ora che disponi di un account GitHub, puoi aggiungerti alla nostra chat principale effettuando il login con GitHub. Presentati dicendo \" Hello World! \"Dì ai campers come hai trovato freeCodeCamp. Dicci anche perché vuoi imparare a programmare. ", + "Ora che disponi di un account GitHub, puoi aggiungerti alla nostra chat principale effettuando il login con GitHub. Si prega di non accedere con Twitter. Presentati dicendo \" Hello World! \"Dì ai campers come hai trovato freeCodeCamp. Dicci anche perché vuoi imparare a programmare. ", "https://gitter.im/FreeCodeCamp/FreeCodeCamp" ], [ @@ -1017,7 +1017,7 @@ [ "//i.imgur.com/OmRmLB4.gif", "Um gif mostrando como clicar no link abaixo para ir à nossa sala de bate-papo e clicar no botão \"entre com GitHub\". Em seguida, você pode clicar no campo de entrada de texto e digitar uma mensagem para os seus colegas campistas.", - "Agora que você tem uma conta GitHub, você pode se juntar à nossa sala de chat principal, fazendo login com GitHub. Apresente-se, diga \"Hello world! \" e diga a seus colegas campistas como você encontrou o freeCodeCamp. Também diga-nos por que você quer aprender a programar.", + "Agora que você tem uma conta GitHub, você pode se juntar à nossa sala de chat principal, fazendo login com GitHub. Por favor, não faça login no Twitter. Apresente-se, diga \"Hello world! \" e diga a seus colegas campistas como você encontrou o freeCodeCamp. Também diga-nos por que você quer aprender a programar.", "https://gitter.im/FreeCodeCamp/FreeCodeCamp" ], [ diff --git a/seed/challenges/01-responsive-web-design/applied-visual-design.json b/seed/challenges/01-responsive-web-design/applied-visual-design.json index 6449d7e04a..efe30a8463 100644 --- a/seed/challenges/01-responsive-web-design/applied-visual-design.json +++ b/seed/challenges/01-responsive-web-design/applied-visual-design.json @@ -1036,41 +1036,15 @@ "challengeType": 0, "translations": {} }, - { - "id": "587d781d367417b2b2512ac7", - "title": "Adjust the Color of an Anchor Tag", - "description": [ - "You can adjust the text color of any text in an element with the color property.", - "
", - "Change the color property of the anchor (a) tag to #000 (black)." - ], - "challengeSeed": [ - "", - "CatPhotoApp" - ], - "tests": [ - "assert($('a').css('color') == 'rgb(0, 0, 0)', 'message: The color of the anchor tag text should be black.')" - ], - "solutions": [], - "hints": [], - "type": "waypoint", - "releasedOn": "Feb 17, 2017", - "challengeType": 0, - "translations": {} - }, { "id": "587d781d367417b2b2512ac8", "title": "Adjust the Hover State of an Anchor Tag", "description": [ "This challenge will touch on the usage of pseudo-classes. A pseudo-class is a keyword that can be added to selectors, in order to select a specific state of the element.", - "Following from the previous challenge, the styling of the anchor tag can be changed for its hover state using the :hover pseudo-class selector. Here's an example that changes the color of the anchor tag to red during its hover state:", + "For example, the styling of an anchor tag can be changed for its hover state using the :hover pseudo-class selector. Here's the CSS to change the color of the anchor tag to red during its hover state:", "
a:hover {
color: red;
}
", "
", - "Change the a tag's CSS so that when the user hovers over it, the color is blue." + "The code editor has a CSS rule to style all a tags black. Add a rule so that when the user hovers over the a tag, the color is blue." ], "challengeSeed": [ "