Merge pull request #8542 from FreeCodeCamp/staging

Release staging
This commit is contained in:
Berkeley Martinez
2016-05-09 16:38:08 -07:00
18 changed files with 112 additions and 47 deletions

View File

@ -15,16 +15,16 @@
#### Type of Change #### Type of Change
<!-- What type of change does your code introduce? Put an `x` in the box that applies. --> <!-- What type of change does your code introduce? Put an `x` in the box that applies. -->
- [ ] Bug fix (non-breaking change which fixes an issue) - [ ] Small bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality) - [ ] New feature (non-breaking change which adds new functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change) - [ ] Breaking change (fix or feature that would change existing functionality)
- [ ] Add new translation (feature adding new translations) - [ ] Add new translation (feature adding new translations)
#### Checklist: #### Checklist:
<!-- Go over all points below, and put an `x` in all the boxes that apply. --> <!-- Go over all points below, and put an `x` in all the boxes that apply. -->
<!-- If you're unsure about any of these, don't hesitate to ask. We're here to help! --> <!-- If you're unsure about any of these, don't hesitate to ask in the Help Contributors room linked above. We're here to help! -->
- [ ] Tested changes locally. - [ ] Tested changes locally.
- [ ] Closes currently open issue (`Closes #XXXX`): Closes - [ ] Closes currently open issue (e.g. `Closes #XXXX`): Closes
#### Description #### Description
<!-- Describe your changes in detail --> <!-- Describe your changes in detail -->

View File

@ -166,7 +166,7 @@ Read the [Wiki article](https://github.com/FreeCodeCamp/FreeCodeCamp/wiki/How-To
- **Do not add the issue number in the PR title**. - **Do not add the issue number in the PR title**.
- Examples: `Add Test Cases to Bonfire Drop It` `Correct typo in Waypoint Size Your Images` - Examples: `Add Test Cases to Bonfire Drop It` `Correct typo in Waypoint Size Your Images`
4. In the body of your PR include a more detailed summary of the changes you made and why. 4. 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 your PR's commit message, append the keyword `closes` and #xxxx (where xxxx is the issue number). Example: `closes #1337`. - 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. This tells GitHub to close the existing issue, if the PR is merged.
5. Indicate if you have tested on a local copy of the site or not. 5. Indicate if you have tested on a local copy of the site or not.

View File

@ -18,8 +18,10 @@ import render from '../common/app/utils/render';
const log = debug('fcc:client'); const log = debug('fcc:client');
const DOMContainer = document.getElementById('fcc'); const DOMContainer = document.getElementById('fcc');
const initialState = window.__fcc__.data; const initialState = window.__fcc__.data;
const csrfToken = window.__fcc__.csrf.token;
initialState.app.csrfToken = csrfToken;
const serviceOptions = { xhrPath: '/services' }; const serviceOptions = { xhrPath: '/services', context: { _csrf: csrfToken } };
Rx.config.longStackSupport = !!debug.enabled; Rx.config.longStackSupport = !!debug.enabled;
const history = createHistory(); const history = createHistory();

View File

@ -2,7 +2,7 @@
* based off of https://github.com/gitterHQ/sidecar * based off of https://github.com/gitterHQ/sidecar
* license: MIT * license: MIT
*/ */
.map-aside { .map-aside {
width:500px; width:500px;
@ -90,6 +90,7 @@
margin: 0 auto; margin: 0 auto;
z-index: 2; z-index: 2;
top: 160px; top: 160px;
left: 0px;
width: 100%; width: 100%;
} }
} }
@ -132,7 +133,6 @@
} }
.mapWrapper { .mapWrapper {
position:absolute;
display: block; display: block;
height: 100%; height: 100%;
width: 100%; width: 100%;

View File

@ -30,6 +30,7 @@ export default handleActions(
username: null, username: null,
picture: null, picture: null,
points: 0, points: 0,
isSignedIn: false isSignedIn: false,
csrfToken: ''
} }
); );

View File

@ -21,7 +21,7 @@ function handleAnswer(getState, dispatch, next, action) {
const state = getState(); const state = getState();
const { id, name, challengeType, tests } = getCurrentHike(state); const { id, name, challengeType, tests } = getCurrentHike(state);
const { const {
app: { isSignedIn }, app: { isSignedIn, csrfToken },
hikesApp: { hikesApp: {
currentQuestion, currentQuestion,
delta = [ 0, 0 ] delta = [ 0, 0 ]
@ -76,7 +76,7 @@ function handleAnswer(getState, dispatch, next, action) {
let updateUser$; let updateUser$;
if (isSignedIn) { if (isSignedIn) {
const body = { id, name, challengeType: +challengeType }; const body = { id, name, challengeType: +challengeType, _csrf: csrfToken };
updateUser$ = postJSON$('/completed-challenge', body) updateUser$ = postJSON$('/completed-challenge', body)
// if post fails, will retry once // if post fails, will retry once
.retry(3) .retry(3)

View File

@ -80,11 +80,15 @@ export default handleActions(
[types.goToNextHike]: state => ({ [types.goToNextHike]: state => ({
...state, ...state,
currentHike: findNextHikeName(state.hikes, state.currentHike), currentHike: findNextHikeName(state.hikes, state.currentHike),
shouldShowQuestions: false,
currentQuestion: 1,
mouse: [ 0, 0 ] mouse: [ 0, 0 ]
}), }),
[types.transitionHike]: state => ({
...state,
showQuestions: false,
currentQuestion: 1
}),
[types.fetchHikesCompleted]: (state, { payload }) => { [types.fetchHikesCompleted]: (state, { payload }) => {
const { hikes, currentHike } = payload; const { hikes, currentHike } = payload;

View File

@ -948,7 +948,7 @@
"<code>var sampleStr = \"Alan said, \\\"Peter is learning JavaScript\\\".\";</code>", "<code>var sampleStr = \"Alan said, \\\"Peter is learning JavaScript\\\".\";</code>",
"This signals to JavaScript that the following quote is not the end of the string, but should instead appear inside the string. So if you were to print this to the console, you would get:", "This signals to JavaScript that the following quote is not the end of the string, but should instead appear inside the string. So if you were to print this to the console, you would get:",
"<code>Alan said, \"Peter is learning JavaScript\".</code>", "<code>Alan said, \"Peter is learning JavaScript\".</code>",
"<h4>Instruction</h4>", "<h4>Instructions</h4>",
"Use <dfn>backslashes</dfn> to assign a string to the <code>myStr</code> variable so that <em>if</em> you were to print it to the console, you would see:", "Use <dfn>backslashes</dfn> to assign a string to the <code>myStr</code> variable so that <em>if</em> you were to print it to the console, you would see:",
"<code>I am a \"double quoted\" string inside \"double quotes\"</code>" "<code>I am a \"double quoted\" string inside \"double quotes\"</code>"
], ],
@ -3757,7 +3757,7 @@
"description": [ "description": [
"In the casino game Blackjack, a player can gain an advantage over the house by keeping track of the relative number of high and low cards remaining in the deck. This is called <a href='https://en.wikipedia.org/wiki/Card_counting' target='_blank'>Card Counting</a>.", "In the casino game Blackjack, a player can gain an advantage over the house by keeping track of the relative number of high and low cards remaining in the deck. This is called <a href='https://en.wikipedia.org/wiki/Card_counting' target='_blank'>Card Counting</a>.",
"Having more high cards remaining in the deck favors the player. Each card is assigned a value according to the table below. When the count is positive, the player should bet high. When the count is zero or negative, the player should bet low.", "Having more high cards remaining in the deck favors the player. Each card is assigned a value according to the table below. When the count is positive, the player should bet high. When the count is zero or negative, the player should bet low.",
"<table class=\"table table-striped\"><thead><tr><th>Count Change</th><th>Cards</th></tr></thead><tbody><tr><td>+1</td><td>2, 3, 4, 5, 6</td></tr><tr><td>0</td><td>7, 8, 9</td></tr><tr><td>-1</td><td>10, 'J', 'Q', 'K','A'</td></tr></tbody></table>", "<table class=\"table table-striped\"><thead><tr><th>Count Change</th><th>Cards</th></tr></thead><tbody><tr><td>+1</td><td>2, 3, 4, 5, 6</td></tr><tr><td>0</td><td>7, 8, 9</td></tr><tr><td>-1</td><td>10, 'J', 'Q', 'K', 'A'</td></tr></tbody></table>",
"You will write a card counting function. It will receive a <code>card</code> parameter and increment or decrement the global <code>count</code> variable according to the card's value (see table). The function will then return a string with the current count and the string <code>\"Bet\"</code> if the count is positive, or <code>\"Hold\"</code> if the count is zero or negative. The current count and the player's decision (<code>\"Bet\"</code> or <code>\"Hold\"</code>) should be separated by a single space.", "You will write a card counting function. It will receive a <code>card</code> parameter and increment or decrement the global <code>count</code> variable according to the card's value (see table). The function will then return a string with the current count and the string <code>\"Bet\"</code> if the count is positive, or <code>\"Hold\"</code> if the count is zero or negative. The current count and the player's decision (<code>\"Bet\"</code> or <code>\"Hold\"</code>) should be separated by a single space.",
"<strong>Example Output</strong><br><code>\"-3 Hold\"<br>\"5 Bet\"</code>", "<strong>Example Output</strong><br><code>\"-3 Hold\"<br>\"5 Bet\"</code>",
"<strong>Hint</strong><br>Do NOT reset <code>count</code> to 0 when value is 7, 8, or 9." "<strong>Hint</strong><br>Do NOT reset <code>count</code> to 0 when value is 7, 8, or 9."

View File

@ -43,6 +43,12 @@
"A gif showing the process of adding Bootstrap to your pen.", "A gif showing the process of adding Bootstrap to your pen.",
"Click the gear in the upper left hand corner of the CSS box, then scroll down to \"Quick add\" and choose Bootstrap. Now give your <code>h1</code> element the class of <code>text-primary</code> to change its color and prove that Bootstrap is now available.", "Click the gear in the upper left hand corner of the CSS box, then scroll down to \"Quick add\" and choose Bootstrap. Now give your <code>h1</code> element the class of <code>text-primary</code> to change its color and prove that Bootstrap is now available.",
"" ""
],
[
"//i.imgur.com/m0pWik2.gif",
"A gif showing the process of turning off auto update preview",
"When using CodePen and Ajax, it is a good idea to turn off automatic preview updating so API calls are not made too often. Too many API calls can sometimes lead to temporary blockages, and may require waiting periods before they can be used again. <br> <div class=\"small\"> To disable automatic preview updating click the \"Settings\" button at the top of the page, then click the \"Behavior\" tab. At the bottom of the page, un-check \"AUTO UPDATE PREVIEW\". Now press \"Run\" at the top of the page to update the preview, and click \"Save\".</div>",
""
] ]
], ],
"challengeSeed": [], "challengeSeed": [],

View File

@ -35,7 +35,16 @@
"LinkedIn reconnait Free Code Camp comme une université. Tu peux avoir accès à notre large réseau de lauréats en ajoutant Free Code Camp à la section éducation de ton profil LinkedIn. Lannée dobtention du diplôme est la prochaine année. Pour le \"Degré\", cest \"Full Stack Web Development Certification\". Pour le \"Domaine détudes\", cest \"Computer Software Engineering\". Puis sauvegardez les changements.", "LinkedIn reconnait Free Code Camp comme une université. Tu peux avoir accès à notre large réseau de lauréats en ajoutant Free Code Camp à la section éducation de ton profil LinkedIn. Lannée dobtention du diplôme est la prochaine année. Pour le \"Degré\", cest \"Full Stack Web Development Certification\". Pour le \"Domaine détudes\", cest \"Computer Software Engineering\". Puis sauvegardez les changements.",
"https://www.linkedin.com/profile/edit-education?school=Free+Code+Camp" "https://www.linkedin.com/profile/edit-education?school=Free+Code+Camp"
] ]
] ],
"titleDe": "Tritt unserem LinkedIn Alumni Netzwerk bei",
"descriptionDe": [
[
"//i.imgur.com/vJyiXzU.gif",
"Ein GIF, das dir zeigt, wie du den unten stehenden Link anklicken kannst und welche Felder du ausfüllen musst, damit du Free Code Camp zu deinem LinkedIn Profil hinzufügst.",
"LinkedIn erkennt Free Code Camp als Universität an. Du bekommst auf unser großes Alumni Netzwerk zugriff, indem du Free Code Camp zum Ausbildungsbereich deines LinkedIn Profils hinzufügst. Setze deinen Abschlusszeitpunkt auf das nächste Jahr. In das Feld \"Abschluss\" schreibe \"Full Stack Web Development Certification\". In das Feld \"Studienfach\" schreibe \"Computer Software Engineering\". Dann klicke auf den \"Speichern\" Button.",
"https://www.linkedin.com/profile/edit-education?school=Free+Code+Camp"
]
]
}, },
{ {
"id": "560adc65cb82ac38a17513c2", "id": "560adc65cb82ac38a17513c2",
@ -70,6 +79,15 @@
"Notre communauté à son propre subreddit sur Reddit. Cest un espace où tu peux poser des questions ou partager des liens avec la communauté. Si tu nas pas encore un compte sur Reddit, tu peux créer un dans quelque secondes tu nas pas besoin dune adresse mail. Tu peux cliquer après sur le bouton \"subscribe\" pour rejoindre notre subreddit. Tu peux rejoindre dautre subreddits listés dans la sidebar.", "Notre communauté à son propre subreddit sur Reddit. Cest un espace où tu peux poser des questions ou partager des liens avec la communauté. Si tu nas pas encore un compte sur Reddit, tu peux créer un dans quelque secondes tu nas pas besoin dune adresse mail. Tu peux cliquer après sur le bouton \"subscribe\" pour rejoindre notre subreddit. Tu peux rejoindre dautre subreddits listés dans la sidebar.",
"https://reddit.com/r/freecodecamp" "https://reddit.com/r/freecodecamp"
] ]
],
"titleDe": "Tritt unserem Subreddit bei",
"descriptionDe": [
[
"//i.imgur.com/DYjJuCG.gif",
"Ein GIF, das dir zeigt, wie du einen Reddit Account anlegen und unserem Free Code Camp Subreddit beitreten kannst.",
"Unsere Community hat ihr eigenes Subreddit auf Reddit. Das ist eine sehr praktische Art und Weise, um Fragen zu stellen und Links mit unserer gesamten Community zu teilen. Wenn du noch keinen Reddit Account hast, kannst du einen in wenigen Sekunden erstellen - du brauchst nicht mal eine E-Mail Adresse. Dann kannst du den \"subscribe\" Button klicken, um unserem Subreddit beizutreten. Wenn du willst, kannst du auch jenen Subreddits folgen, die wir in unserer Sidebar gelistet haben.",
"https://reddit.com/r/freecodecamp"
]
] ]
}, },
{ {
@ -123,6 +141,21 @@
"Une fois identifié, tu peux visiter la publication de Free Code Camp sur Medium et cliquer sur \"follow\". Nos campers publient plusieurs articles chaque semaine.", "Une fois identifié, tu peux visiter la publication de Free Code Camp sur Medium et cliquer sur \"follow\". Nos campers publient plusieurs articles chaque semaine.",
"https://medium.freecodecamp.com" "https://medium.freecodecamp.com"
] ]
],
"titleDe": "Lese Programmier-Nachrichten auf unserer Medium Seite",
"descriptionDe": [
[
"//i.imgur.com/FxSOL4a.gif",
"Ein GIF, das dir zeigt, wie du einen Medium Account anlegen kannst.",
"Unsere Community hat eine Medium Seite, auf der wir viele Artikel über Software Entwicklung veröffentlichen. Wenn du noch keinen Medium Account hast, kannst du dem Link folgen und dich entweder mit einem Account aus einem Social Network oder einer E-Mail Adresse (sie senden dir eine E-Mail, die du durchklicken kannst, um dir einen Account anzulegen.). Wenn du ein Thema ausgewählt hast, das dich interessiert, kannst du den weiteren Schritten folgen.",
"https://www.medium.com"
],
[
"//i.imgur.com/zhhywSX.gif",
"Ein GIF, das dir zeigt, wie du den \"follow\" Button klicken kannst, um der Free Code Camp Seite zu folgen.",
"Bist du erstmal eingeloggt, kannst du auf die Medium Seite von Free Code Camp gehen und den \"follow\" Button klicken. Unsere Camper veröffentlichen jede Woche mehrere Artikel.",
"https://medium.freecodecamp.com"
]
] ]
}, },
{ {
@ -158,6 +191,15 @@
"Nos campers codent fréquemment en direct sur Twitch.tv, un site de streaming populaire. Tu peux créer un compte en moins dune minute, et suivre la chaîne de Free Code Camp. Une fois suivi, tu auras loption de recevoir un email à chaque fois quun de nos campers est en direct. Et donc tu peux rejoindre plusieurs campers pour regarder et interagir sur le salon de chat. Cest une façon dapprendre en regardant les autres coder.", "Nos campers codent fréquemment en direct sur Twitch.tv, un site de streaming populaire. Tu peux créer un compte en moins dune minute, et suivre la chaîne de Free Code Camp. Une fois suivi, tu auras loption de recevoir un email à chaque fois quun de nos campers est en direct. Et donc tu peux rejoindre plusieurs campers pour regarder et interagir sur le salon de chat. Cest une façon dapprendre en regardant les autres coder.",
"https://twitch.tv/freecodecamp" "https://twitch.tv/freecodecamp"
] ]
],
"titleDe": "Schaue uns auf Twitch.tv Live beim Programmieren zu",
"descriptionDe": [
[
"//i.imgur.com/8rtyRY1.gif",
"Ein GIF, das dir zeigt, wie du dich bei Twitch.tv anmelden und unserem Kanal folgen kannst.",
"Unsere Camper programmieren oft Live auf Twitch.tv, einer populären Streaming-Website. Du kannst in weniger als einer Minute einen Account anlegen und dann dem Kanal von Free Code Camp folgen. Wenn du dem Kanal folgst, hast du die Option E-Mail Benachrichtigungen zu bekommen, sobald einer unserer Camper live geht. Dann kannst du Dutzenden Campern folgen und ihnen beim Programmieren zusehen sowie in Chats interagieren. Das ist eine lustige und lockere Art und Weise, um von anderen Personen zu lernen, wie sie ihre Projekte umsetzen.",
"https://twitch.tv/freecodecamp"
]
] ]
}, },
{ {
@ -192,7 +234,16 @@
"Tu peux définir un but et tengager à verser une somme dargent pour aider une organisation à but non lucratif chaque mois jusquà atteindre ton objectif. Cela va te donner une motivation externe dans ta journée dapprentissage, mais aussi une opportunité pour aider ces organisations. Choisi un but, et un montant à verser. Quand tu vas cliquer sur \"commit\", la page des dons de lorganisation va souvrir. Cette étape est optionnel, et tu peux annuler ou arrêter ton engagement à nimporte quel instant.", "Tu peux définir un but et tengager à verser une somme dargent pour aider une organisation à but non lucratif chaque mois jusquà atteindre ton objectif. Cela va te donner une motivation externe dans ta journée dapprentissage, mais aussi une opportunité pour aider ces organisations. Choisi un but, et un montant à verser. Quand tu vas cliquer sur \"commit\", la page des dons de lorganisation va souvrir. Cette étape est optionnel, et tu peux annuler ou arrêter ton engagement à nimporte quel instant.",
"/commit" "/commit"
] ]
] ],
"titleDe": "Verpflichte dich zu einem Ziel und einer gemeinnützigen Organisation",
"descriptionDe": [
[
"//i.imgur.com/Og1ifsn.gif",
"Ein GIF, das dir zeigt, wie du dich einem Ziel auf Free Code Camp verpflichten kannst und versprichst, eine monatliche Spende an eine gemeinnützige Organisation zu entrichten, um externe Motivation zur Erreichung deines Ziels zu haben.",
"Du kannst dir ein Ziel setzen und versprechen, einer gemeinnützigen Organisation eine monatliche Spende zu entrichten, bis du dieses Ziel erreicht hast. Das gibt dir externe Motivation in deinem Bestreben programmieren zu lernen - und eröffnet von Anfang an die Gelegenheit gemeinnützigen Organisationen zu helfen. Wähle dein Ziel und dann eine monatliche Spende. Wenn du auf \"verpflichten\" klickst, öffnet sich die Spendenseite der gemeinnützigen Organisation in einem neuen Tab. Dieser Schritt ist optional, du kannst deine Verpflichtung jederzeit ändern oder stoppen.",
"/verpflichten"
]
]
} }
] ]
} }

View File

@ -2154,7 +2154,7 @@
"tests": [ "tests": [
"assert($(\"input[placeholder]\").length > 0, 'message: Add a <code>placeholder</code> attribute text <code>input</code> element.');", "assert($(\"input[placeholder]\").length > 0, 'message: Add a <code>placeholder</code> attribute text <code>input</code> element.');",
"assert($(\"input\") && $(\"input\").attr(\"placeholder\") && $(\"input\").attr(\"placeholder\").match(/cat\\s+photo\\s+URL/gi), 'message: Set the value of your placeholder attribute to \"cat photo URL\".');", "assert($(\"input\") && $(\"input\").attr(\"placeholder\") && $(\"input\").attr(\"placeholder\").match(/cat\\s+photo\\s+URL/gi), 'message: Set the value of your placeholder attribute to \"cat photo URL\".');",
"assert($(\"input[type=text]\").length > 0 && code.match(/<input.*(text|URL)\\s*[\"\\']\\s*\\/?>/gi), 'message: The finished <code>input</code> element should have valid syntax.');" "assert($(\"input[type=text]\").length > 0 && code.match(/<input((\\s+\\w+(\\s*=\\s*(?:\".*?\"|'.*?'|[\\^'\">\\s]+))?)+\\s*|\\s*)\\/?>/gi), 'message: The finished <code>input</code> element should have valid syntax.');"
], ],
"type": "waypoint", "type": "waypoint",
"titleEs": "Agrega un texto de relleno a un campo de texto", "titleEs": "Agrega un texto de relleno a un campo de texto",
@ -4265,7 +4265,7 @@
"assert($(\"h1\").hasClass(\"blue-text\"), 'message: Your <code>h1</code> element should have the class <code>blue-text</code>.');", "assert($(\"h1\").hasClass(\"blue-text\"), 'message: Your <code>h1</code> element should have the class <code>blue-text</code>.');",
"assert($(\"h1\").attr(\"id\") === \"orange-text\", 'message: Your <code>h1</code> element should have the id of <code>orange-text</code>.');", "assert($(\"h1\").attr(\"id\") === \"orange-text\", 'message: Your <code>h1</code> element should have the id of <code>orange-text</code>.');",
"assert(code.match(/<h1.*style/gi) && code.match(/<h1.*style.*color\\s*?:/gi), 'message: Your <code>h1</code> element should have the inline style of <code>color&#58; white</code>.');", "assert(code.match(/<h1.*style/gi) && code.match(/<h1.*style.*color\\s*?:/gi), 'message: Your <code>h1</code> element should have the inline style of <code>color&#58; white</code>.');",
"assert(code.match(/\\.pink-text\\s+\\{\\s+color:.*pink.*!important;\\s+\\}/gi), 'message: Your <code>pink-text</code> class declaration should have the <code>!important</code> keyword to override all other declarations.');", "assert(code.match(/\\.pink-text\\s*?\\{\\s+color:.*pink.*!important;\\s+\\}/gi), 'message: Your <code>pink-text</code> class declaration should have the <code>!important</code> keyword to override all other declarations.');",
"assert($(\"h1\").css(\"color\") === \"rgb(255, 192, 203)\", 'message: Your <code>h1</code> element should be pink.');" "assert($(\"h1\").css(\"color\") === \"rgb(255, 192, 203)\", 'message: Your <code>h1</code> element should be pink.');"
], ],
"descriptionPtBR": [ "descriptionPtBR": [

View File

@ -550,7 +550,8 @@
"type": "bonfire", "type": "bonfire",
"MDNlinks": [ "MDNlinks": [
"RegExp", "RegExp",
"HTML Entities" "HTML Entities",
"String.replace()"
], ],
"isRequired": true, "isRequired": true,
"challengeType": 5, "challengeType": 5,

View File

@ -45,7 +45,7 @@
], ],
"tests": [ "tests": [
"assert(code.match(/<\\/script\\s*>/g) && code.match(/<script(\\sasync|\\sdefer)*(\\s(charset|src|type)\\s*=\\s*[\"\\']+[^\"\\']*[\"\\']+)*(\\sasync|\\sdefer)*\\s*>/g) && code.match(/<\\/script\\s*>/g).length === code.match(/<script(\\sasync|\\sdefer)*(\\s(charset|src|type)\\s*=\\s*[\"\\']+[^\"\\']*[\"\\']+)*(\\sasync|\\sdefer)*\\s*>/g).length, 'message: Create a <code>script</code> element making sure it is valid and has a closing tag.');", "assert(code.match(/<\\/script\\s*>/g) && code.match(/<script(\\sasync|\\sdefer)*(\\s(charset|src|type)\\s*=\\s*[\"\\']+[^\"\\']*[\"\\']+)*(\\sasync|\\sdefer)*\\s*>/g) && code.match(/<\\/script\\s*>/g).length === code.match(/<script(\\sasync|\\sdefer)*(\\s(charset|src|type)\\s*=\\s*[\"\\']+[^\"\\']*[\"\\']+)*(\\sasync|\\sdefer)*\\s*>/g).length, 'message: Create a <code>script</code> element making sure it is valid and has a closing tag.');",
"assert(code.match(/\\$\\s*?\\(\\s*?document\\)\\.ready\\s*?\\(\\s*?function\\s*?\\(\\s*?\\)\\s*?\\{/g), 'message: You should add <code>$&#40;document&#41;.ready&#40;function&#40;&#41; {</code> to the beginning of your <code>script</code> element.');", "assert(code.match(/\\$\\s*?\\(\\s*?document\\s*?\\)\\.ready\\s*?\\(\\s*?function\\s*?\\(\\s*?\\)\\s*?\\{/g), 'message: You should add <code>$&#40;document&#41;.ready&#40;function&#40;&#41; {</code> to the beginning of your <code>script</code> element.');",
"assert(code.match(/\\n*?\\s*?\\}\\s*?\\);/g), 'message: Close your <code>$&#40;document&#41;.ready&#40;function&#40;&#41; {</code> function with <code>}&#41;;</code>');" "assert(code.match(/\\n*?\\s*?\\}\\s*?\\);/g), 'message: Close your <code>$&#40;document&#41;.ready&#40;function&#40;&#41; {</code> function with <code>}&#41;;</code>');"
], ],
"type": "waypoint", "type": "waypoint",
@ -200,10 +200,10 @@
"titleDe": "Elemente anhand von Klassen mit jQuery auswählen", "titleDe": "Elemente anhand von Klassen mit jQuery auswählen",
"descriptionDe": [ "descriptionDe": [
"Siehst du, wie wir alle deine <code>Button</code> Elemente hüpfen haben lassen? Wir haben sie mit <code>$(\"button\")</code> ausgewählt, dann CSS-Klassen mit <code>.addClass(\"animated bounce\");</code> hinzugefügt.", "Siehst du, wie wir alle deine <code>Button</code> Elemente hüpfen haben lassen? Wir haben sie mit <code>$(\"button\")</code> ausgewählt, dann CSS-Klassen mit <code>.addClass(\"animated bounce\");</code> hinzugefügt.",
"Du hast gerade jQuery's <code>.addClass()</code> Funktion genutzt, die dir erlaubt, Klassen zu Elemente hinzuzufügen.", "Du hast gerade jQuery's <code>.addClass()</code> Funktion genutzt, die dir erlaubt, Klassen zu Elemente hinzuzufügen.",
"Wähle als erstes deine <code>div</code> Elemente mit der Klasse <code>well</code>, indem du den <code>$(\".well\")</code> Selektor nutzt.", "Wähle als erstes deine <code>div</code> Elemente mit der Klasse <code>well</code>, indem du den <code>$(\".well\")</code> Selektor nutzt.",
"Bedenke, dass du - genauso wie bei CSS-Deklarationen - einen <code>.</code> vor den Namen der Klasse setzen musst.", "Bedenke, dass du - genauso wie bei CSS-Deklarationen - einen <code>.</code> vor den Namen der Klasse setzen musst.",
"Dann nutze die jQuery Funktion <code>.addClass()</code> um die Klassen <code>animated</code> und <code>shake</code> hinzuzufügen.", "Dann nutze die jQuery Funktion <code>.addClass()</code> um die Klassen <code>animated</code> und <code>shake</code> hinzuzufügen.",
"Zum Beispiel könntest du alle Elemente mit der Klasse <code>text-primary</code> schütteln lassen, indem du folgendes zu deiner <code>Document Ready Funktion</code> hinzufügst:", "Zum Beispiel könntest du alle Elemente mit der Klasse <code>text-primary</code> schütteln lassen, indem du folgendes zu deiner <code>Document Ready Funktion</code> hinzufügst:",
"<code>$(\".text-primary\").addClass(\"animated shake\");</code>" "<code>$(\".text-primary\").addClass(\"animated shake\");</code>"
] ]
@ -344,8 +344,7 @@
"title": "Target the same element with multiple jQuery Selectors", "title": "Target the same element with multiple jQuery Selectors",
"description": [ "description": [
"Now you know three ways of targeting elements: by type: <code>$(\"button\")</code>, by class: <code>$(\".btn\")</code>, and by id <code>$(\"#target1\")</code>.", "Now you know three ways of targeting elements: by type: <code>$(\"button\")</code>, by class: <code>$(\".btn\")</code>, and by id <code>$(\"#target1\")</code>.",
"Although it is possible to add multiple classes in a single <code>.addClass()</code> call, let's add them to the same element in three different ways.", "Using <code>.addClass()</code>, add only one class at a time to the same element, three different ways:",
"Using each of the above jQuery selectors and the <code>addClass()</code> function:",
"Add the <code>animated</code> class to all elements with type <code>button</code>.", "Add the <code>animated</code> class to all elements with type <code>button</code>.",
"Add the <code>shake</code> class to all the buttons with class <code>.btn</code>.", "Add the <code>shake</code> class to all the buttons with class <code>.btn</code>.",
"Add the <code>btn-primary</code> class to the button with id <code>#target1</code>." "Add the <code>btn-primary</code> class to the button with id <code>#target1</code>."
@ -468,7 +467,7 @@
"Vamos a quitar la clase <code>btn-default</code> de todos nuestros elementos <code>button</code>." "Vamos a quitar la clase <code>btn-default</code> de todos nuestros elementos <code>button</code>."
], ],
"titleDe": "Entferne Klassen von einem Element mit jQuery", "titleDe": "Entferne Klassen von einem Element mit jQuery",
"descriptionDe": [ "descriptionDe": [
"Genauso wie du Klassen mit der jQuery Funktion <code>addClass()</code> hinzufügen kannst, kannst du mit der jQuery Funktion <code>removeClass()</code> Klassen entfernen.", "Genauso wie du Klassen mit der jQuery Funktion <code>addClass()</code> hinzufügen kannst, kannst du mit der jQuery Funktion <code>removeClass()</code> Klassen entfernen.",
"So könntest du das bei einem spezifischen Button machen:", "So könntest du das bei einem spezifischen Button machen:",
"<code>$(\"#target2\").removeClass(\"btn-default\");</code>", "<code>$(\"#target2\").removeClass(\"btn-default\");</code>",
@ -1030,7 +1029,7 @@
"Da a todos los hijos de tu elemento <code>right-well</code> el color naranja." "Da a todos los hijos de tu elemento <code>right-well</code> el color naranja."
], ],
"titleDe": "Wähle Kinder-Elemente mit jQuery aus", "titleDe": "Wähle Kinder-Elemente mit jQuery aus",
"descriptionDe": [ "descriptionDe": [
"Viele HTML-Elemente haben <code>Kinder-Elemente</code>, die ihre Eigenschaften von ihren Eltern-Elementen <code>erben</code>.", "Viele HTML-Elemente haben <code>Kinder-Elemente</code>, die ihre Eigenschaften von ihren Eltern-Elementen <code>erben</code>.",
"Zum Beispiel ist jedes HTML-Element ein Kind-Element des <code>body</code> Elements und dein <code>\"jQuery Playground\"</code> <code>h3</code> Element ist ein Kind-Element deines <code>&#60;div class=\"container-fluid\"&#62</code> Elements.", "Zum Beispiel ist jedes HTML-Element ein Kind-Element des <code>body</code> Elements und dein <code>\"jQuery Playground\"</code> <code>h3</code> Element ist ein Kind-Element deines <code>&#60;div class=\"container-fluid\"&#62</code> Elements.",
"jQuery hat eine Funktion namens <code>children()</code>, die es dir erlaubt, auf die Kinder-Elemente des von dir ausgewählten Elements zuzugreifen.", "jQuery hat eine Funktion namens <code>children()</code>, die es dir erlaubt, auf die Kinder-Elemente des von dir ausgewählten Elements zuzugreifen.",
@ -1250,8 +1249,8 @@
"Pero vamos a hacer algo más dramático. Añade las clases <code>animated</code> y <code>hinge</code> a tu elemento <code>body</code>." "Pero vamos a hacer algo más dramático. Añade las clases <code>animated</code> y <code>hinge</code> a tu elemento <code>body</code>."
], ],
"titleDe": "Mit jQuery die gesamte Seite modifizieren", "titleDe": "Mit jQuery die gesamte Seite modifizieren",
"descriptionDe": [ "descriptionDe": [
"Genug mit unserem jQuery Spielplatz herumgespielt. Reißen wir ihn ein!", "Genug mit unserem jQuery Spielplatz herumgespielt. Reißen wir ihn ein!",
"jQuery kann auch das <code>body</code> Element auswählen.", "jQuery kann auch das <code>body</code> Element auswählen.",
"Hier siehst du, wie wir den gesamten <code>body</code> Bereich ausblenden können: <code> $(\"body\").addClass(\"animated fadeOut\");</code>", "Hier siehst du, wie wir den gesamten <code>body</code> Bereich ausblenden können: <code> $(\"body\").addClass(\"animated fadeOut\");</code>",
"Aber lass uns noch etwas Dramatischeres machen. Füge die Klassen <code>animated</code> und <code>hinge</code> zu deinem <code>body</code> Element hinzu." "Aber lass uns noch etwas Dramatischeres machen. Füge die Klassen <code>animated</code> und <code>hinge</code> zu deinem <code>body</code> Element hinzu."

View File

@ -567,7 +567,7 @@
"description": [ "description": [
"You can use the <code>split</code> method to split a string into an array.", "You can use the <code>split</code> method to split a string into an array.",
"<code>split</code> uses the argument you pass in as a delimiter to determine which points the string should be split at.", "<code>split</code> uses the argument you pass in as a delimiter to determine which points the string should be split at.",
"Here is an example of <code>split</code> being used to split an array at every <code>s</code> character:", "Here is an example of <code>split</code> being used to split a string at every <code>s</code> character:",
"<code>var array = string.split('s');</code>", "<code>var array = string.split('s');</code>",
"Use <code>split</code> to create an array of words from <code>string</code> and assign it to <code>array</code>." "Use <code>split</code> to create an array of words from <code>string</code> and assign it to <code>array</code>."
], ],

View File

@ -258,6 +258,7 @@
"<strong>User Story:</strong> I can pass a URL as a parameter and I will receive a shortened URL in the JSON response.", "<strong>User Story:</strong> I can pass a URL as a parameter and I will receive a shortened URL in the JSON response.",
"<strong>User Story:</strong> If I pass an invalid URL that doesn't follow the valid http://www.example.com format, the JSON response will contain an error instead.", "<strong>User Story:</strong> If I pass an invalid URL that doesn't follow the valid http://www.example.com format, the JSON response will contain an error instead.",
"<strong>User Story:</strong> When I visit that shortened URL, it will redirect me to my original link.", "<strong>User Story:</strong> When I visit that shortened URL, it will redirect me to my original link.",
"<strong>Pro Tip:</strong> Checkout this <a href='https://github.com/FreeCodeCamp/FreeCodeCamp/wiki/Using-MongoDB-And-Deploying-To-Heroku/' target='_blank'>wiki article</a> for tips on integrating MongoDB on Heroku.",
"Once you've finished implementing these user stories, click the \"I've completed this challenge\" button and enter the URLs for both your GitHub repository and your live app running on Heroku.", "Once you've finished implementing these user stories, click the \"I've completed this challenge\" button and enter the URLs for both your GitHub repository and your live app running on Heroku.",
"You can get feedback on your project from fellow campers by sharing it in our <a href='//gitter.im/freecodecamp/codereview' target='_blank'>Code Review Chatroom</a>. You can also share it on Twitter and your city's Campsite (on Facebook)." "You can get feedback on your project from fellow campers by sharing it in our <a href='//gitter.im/freecodecamp/codereview' target='_blank'>Code Review Chatroom</a>. You can also share it on Twitter and your city's Campsite (on Facebook)."
], ],

View File

@ -3,6 +3,9 @@ export default function globalLocals() {
// Make user object available in templates. // Make user object available in templates.
res.locals.user = req.user; res.locals.user = req.user;
res.locals._csrf = req.csrfToken ? req.csrfToken() : null; res.locals._csrf = req.csrfToken ? req.csrfToken() : null;
if (req.csrfToken) {
res.expose({ token: res.locals._csrf }, 'csrf');
}
next(); next();
}; };
} }

View File

@ -15,17 +15,10 @@ block content
a.btn.btn-lg.btn-block.btn-social.btn-twitter(href='/auth/twitter') a.btn.btn-lg.btn-block.btn-social.btn-twitter(href='/auth/twitter')
i.fa.fa-twitter i.fa.fa-twitter
| Sign in with Twitter | Sign in with Twitter
br
p
strong IMPORTANT NOTICE
br
em These options are under deprecation and will be removed soon.
br
em After you are signed in, go to the settings page and add GitHub and/or Email as your sign in option
script. script.
$(document).ready(function() { $(document).ready(function() {
var method = localStorage.getItem('lastSigninMethod'), var method = localStorage.getItem('lastSigninMethodDeprecated'),
btnSelector = 'a.btn.btn-lg.btn-block.btn-social'; btnSelector = 'a.btn.btn-lg.btn-block.btn-social';
if (method) { if (method) {
try { try {
@ -51,6 +44,6 @@ block content
$(this).removeClass('active'); $(this).removeClass('active');
obj.methodClass = $(this).attr('class').split(' ').pop(); obj.methodClass = $(this).attr('class').split(' ').pop();
obj.methodLink = $(this).attr('href'); obj.methodLink = $(this).attr('href');
localStorage.setItem('lastSigninMethod', JSON.stringify(obj)); localStorage.setItem('lastSigninMethodDeprecated', JSON.stringify(obj));
}); });
}); });

View File

@ -1,9 +1,9 @@
extends ../layout extends ../layout
block content block content
.text-center .text-center
h2 New to Free Code Camp? h2 New to Free Code Camp?
br br
.button-spacer .button-spacer
| Sign up now: | Sign up now:
a.btn.btn-lg.btn-block.btn-social.btn-primary(href='/email-signup') a.btn.btn-lg.btn-block.btn-social.btn-primary(href='/email-signup')
i.fa.fa-envelope i.fa.fa-envelope
@ -13,7 +13,7 @@ block content
| Sign up with GitHub | Sign up with GitHub
.spacer .spacer
hr hr
.spacer .spacer
h2 Are you a returning camper? h2 Are you a returning camper?
br br
.button-spacer .button-spacer
@ -41,7 +41,7 @@ block content
} }
$.each($(btnSelector), function(i, item) { $.each($(btnSelector), function(i, item) {
if ( if (
$(item).attr('href') === obj.methodLink && $(item).text() === obj.method &&
$(item).hasClass(obj.methodClass) $(item).hasClass(obj.methodClass)
) { ) {
$(item).addClass('active'); $(item).addClass('active');
@ -55,7 +55,11 @@ block content
var obj = {}; var obj = {};
$(this).removeClass('active'); $(this).removeClass('active');
obj.methodClass = $(this).attr('class').split(' ').pop(); obj.methodClass = $(this).attr('class').split(' ').pop();
obj.methodLink = $(this).attr('href'); obj.method = $(this).text();
localStorage.setItem('lastSigninMethod', JSON.stringify(obj)); if(obj.method === "Sign in with Email" || obj.method === "Sign in with GitHub") {
localStorage.setItem('lastSigninMethod', JSON.stringify(obj));
} else {
localStorage.removeItem('lastSigninMethod');
}
}); });
}); });