chore: Remove unused/deprecated files

This commit is contained in:
Berkeley Martinez
2017-01-19 17:56:07 -08:00
parent 7bd403a202
commit 86d4b5e841
25 changed files with 0 additions and 2254 deletions

View File

@@ -1,21 +0,0 @@
window.common = (function(global) {
const {
loopProtect,
common = { init: [] }
} = global;
loopProtect.hit = function hit(line) {
var err = 'Error: Exiting potential infinite loop at line ' +
line +
'. To disable loop protection, write: \n\\/\\/ noprotect\nas the first' +
'line. Beware that if you do have an infinite loop in your code' +
'this will crash your browser.';
console.error(err);
};
common.addLoopProtect = function addLoopProtect(code = '') {
return loopProtect(code);
};
return common;
})(window);

View File

@@ -1,217 +0,0 @@
window.common = (function(global) {
const {
$,
Rx: { Observable },
common = { init: [] },
Mousetrap
} = global;
common.ctrlEnterClickHandler = function ctrlEnterClickHandler(e) {
// ctrl + enter or cmd + enter
if (
e.keyCode === 13 &&
(e.metaKey || e.ctrlKey)
) {
$('#complete-courseware-dialog').off('keydown', ctrlEnterClickHandler);
if ($('#submit-challenge').length > 0) {
$('#submit-challenge').click();
} else {
window.location = '/challenges/next-challenge?id=' + common.challengeId;
}
}
};
common.init.push(function($) {
var $marginFix = $('.innerMarginFix');
$marginFix.css('min-height', $marginFix.height());
common.submitBtn$ = Observable.fromEvent($('#submitButton'), 'click');
common.resetBtn$ = Observable.fromEvent($('#reset-button'), 'click');
// init modal keybindings on open
$('#complete-courseware-dialog').on('shown.bs.modal', function() {
$('#complete-courseware-dialog').keydown(common.ctrlEnterClickHandler);
});
// remove modal keybinds on close
$('#complete-courseware-dialog').on('hidden.bs.modal', function() {
$('#complete-courseware-dialog').off(
'keydown',
common.ctrlEnterClickHandler
);
});
// set focus keybind
Mousetrap.bind(['command+shift+e', 'ctrl+shift+e'], () => {
common.editor.focus();
});
// video checklist binding
$('.challenge-list-checkbox').on('change', function() {
var checkboxId = $(this).parent().parent().attr('id');
if ($(this).is(':checked')) {
$(this).parent().siblings().children().addClass('faded');
if (!localStorage || !localStorage[checkboxId]) {
localStorage[checkboxId] = true;
}
}
if (!$(this).is(':checked')) {
$(this).parent().siblings().children().removeClass('faded');
if (localStorage[checkboxId]) {
localStorage.removeItem(checkboxId);
}
}
});
$('.checklist-element').each(function() {
var checklistElementId = $(this).attr('id');
if (localStorage[checklistElementId]) {
$(this).children().children('li').addClass('faded');
$(this).children().children('input').trigger('click');
}
});
// video challenge submit
$('#next-courseware-button').on('click', function() {
$('#next-courseware-button').unbind('click');
if ($('.signup-btn-nav').length < 1) {
var data;
var solution = $('#public-url').val() || null;
var githubLink = $('#github-url').val() || null;
switch (common.challengeType) {
case common.challengeTypes.VIDEO:
data = {
id: common.challengeId,
name: common.challengeName,
challengeType: +common.challengeType
};
$.ajax({
url: '/completed-challenge/',
type: 'POST',
data: JSON.stringify(data),
contentType: 'application/json',
dataType: 'json'
})
.success(function(res) {
if (!res) {
return;
}
window.location.href = '/challenges/next-challenge?id=' +
common.challengeId;
})
.fail(function() {
window.location.replace(window.location.href);
});
break;
case common.challengeTypes.BASEJUMP:
case common.challengeTypes.ZIPLINE:
data = {
id: common.challengeId,
name: common.challengeName,
challengeType: +common.challengeType,
solution,
githubLink
};
$.ajax({
url: '/completed-zipline-or-basejump/',
type: 'POST',
data: JSON.stringify(data),
contentType: 'application/json',
dataType: 'json'
})
.success(function() {
window.location.href = '/challenges/next-challenge?id=' +
common.challengeId;
})
.fail(function() {
window.location.replace(window.location.href);
});
break;
case common.challengeTypes.BONFIRE:
window.location.href = '/challenges/next-challenge?id=' +
common.challengeId;
break;
default:
console.log('Happy Coding!');
break;
}
}
});
if (common.challengeName) {
window.ga('send', 'event', 'Challenge', 'loaded', common.gaName);
}
$('.modal').on('show.bs.modal', function() {
$('.gitter-chat-embed, .map-aside')
.addClass('is-collapsed');
});
$('#complete-courseware-dialog').on('hidden.bs.modal', function() {
if (common.editor.focus) {
common.editor.focus();
}
});
$('#trigger-issue-modal').on('click', function() {
$('#issue-modal').modal('show');
});
$('#trigger-help-modal').on('click', function() {
$('#help-modal').modal('show');
});
$('#trigger-reset-modal').on('click', function() {
$('#reset-modal').modal('show');
});
$('#trigger-pair-modal').on('click', function() {
$('#pair-modal').modal('show');
});
$('#completed-courseware').on('click', function() {
$('#complete-courseware-dialog').modal('show');
});
$('#show-solution').on('click', function() {
$('#complete-courseware-dialog').modal('hide');
});
$('#challenge-help-btn').on('click', function() {
$('.map-aside, #chat-embed-main').addClass('is-collapsed');
});
$('#help-ive-found-a-bug-wiki-article').on('click', function() {
window.open(
'http://forum.freecodecamp.com/t/how-to-report-a-bug/19543',
'_blank'
);
});
$('#search-issue').on('click', function() {
var queryIssue = window.location.href
.toString()
.split('?')[0]
.replace(/(#*)$/, '');
window.open(
'https://github.com/FreeCodeCamp/FreeCodeCamp/issues?q=' +
'is:issue is:all ' +
(common.challengeName) +
' OR ' +
queryIssue
.substr(queryIssue.lastIndexOf('challenges/') + 11)
.replace('/', ''), '_blank');
});
});
return common;
}(window));

View File

@@ -1,69 +0,0 @@
// depends on: codeUri
window.common = (function(global) {
const {
localStorage,
common = { init: [] }
} = global;
const {
replaceNoprotect
} = common;
var challengePrefix = [
'Bonfire: ',
'Waypoint: ',
'Zipline: ',
'Basejump: ',
'Checkpoint: '],
item;
var codeStorage = {
getStoredValue(key) {
if (
!localStorage ||
typeof localStorage.getItem !== 'function' ||
!key ||
typeof key !== 'string'
) {
console.log('unable to read from storage');
return '';
}
if (localStorage.getItem(key + 'Val')) {
return '' + localStorage.getItem(key + 'Val');
} else {
for (var i = 0; i <= challengePrefix.length; i++) {
item = localStorage.getItem(challengePrefix[i] + key + 'Val');
if (item) {
return '' + item;
}
}
}
return null;
},
isAlive: function(key) {
var val = this.getStoredValue(key);
return val !== 'null' &&
val !== 'undefined' &&
(val && val.length > 0);
},
updateStorage(key, code) {
if (
!localStorage ||
typeof localStorage.setItem !== 'function' ||
!key ||
typeof key !== 'string'
) {
console.log('unable to save to storage');
return code;
}
localStorage.setItem(key + 'Val', replaceNoprotect(code));
return code;
}
};
common.codeStorage = codeStorage;
return common;
}(window, window.common));

View File

@@ -1,148 +0,0 @@
// store code in the URL
window.common = (function(global) {
const {
encodeURIComponent: encode,
decodeURIComponent: decode,
location,
history,
common = { init: [] }
} = global;
const {
replaceScriptTags,
replaceSafeTags,
replaceFormActionAttr,
replaceFccfaaAttr,
replaceNoprotect
} = common;
const queryRegex = /^(\?|#\?)/;
function encodeFcc(val) {
return replaceScriptTags(replaceFormActionAttr(replaceNoprotect(val)));
}
function decodeFcc(val) {
return replaceSafeTags(replaceFccfaaAttr(val));
}
var codeUri = {
encode: function(code) {
return encode(code);
},
decode: function(code) {
try {
return decode(code);
} catch (ignore) {
return null;
}
},
isInQuery: function(query) {
var decoded = codeUri.decode(query);
if (!decoded || typeof decoded.split !== 'function') {
return false;
}
return decoded
.replace(queryRegex, '')
.split('&')
.reduce(function(found, param) {
var key = param.split('=')[0];
if (key === 'solution') {
return true;
}
return found;
}, false);
},
isAlive: function() {
return codeUri.enabled &&
codeUri.isInQuery(location.search) ||
codeUri.isInQuery(location.hash);
},
getKeyInQuery(query, keyToFind = '') {
return query
.split('&')
.reduce(function(oldValue, param) {
var key = param.split('=')[0];
var value = param
.split('=')
.slice(1)
.join('=');
if (key === keyToFind) {
return value;
}
return oldValue;
}, null);
},
getSolutionFromQuery(query = '') {
return decodeFcc(
codeUri.decode(codeUri.getKeyInQuery(query, 'solution'))
);
},
parse: function() {
if (!codeUri.enabled) {
return null;
}
var query;
if (location.search && codeUri.isInQuery(location.search)) {
query = location.search.replace(/^\?/, '');
if (history && typeof history.replaceState === 'function') {
history.replaceState(
history.state,
null,
location.href.split('?')[0]
);
location.hash = '#?' + encodeFcc(query);
}
} else {
query = location.hash.replace(/^\#\?/, '');
}
if (!query) {
return null;
}
return this.getSolutionFromQuery(query);
},
querify: function(solution) {
if (!codeUri.enabled) {
return null;
}
if (history && typeof history.replaceState === 'function') {
// grab the url up to the query
// destroy any hash symbols still clinging to life
const url = (location.href.split('?')[0]).replace(/(#*)$/, '');
history.replaceState(
history.state,
null,
url +
'#?' +
(codeUri.shouldRun() ? '' : 'run=disabled&') +
'solution=' +
codeUri.encode(encodeFcc(solution))
);
} else {
location.hash = '?solution=' +
codeUri.encode(encodeFcc(solution));
}
return solution;
},
enabled: true,
shouldRun() {
return !this.getKeyInQuery(
(location.search || location.hash).replace(queryRegex, ''),
'run'
);
}
};
common.init.push(function() {
codeUri.parse();
});
common.codeUri = codeUri;
common.shouldRun = () => codeUri.shouldRun();
return common;
}(window));

View File

@@ -1,119 +0,0 @@
window.common = (function(global) {
const {
Rx: { Subject, Observable },
CodeMirror,
emmetCodeMirror,
common = { init: [] }
} = global;
const { challengeType = '0', challengeTypes } = common;
if (
!CodeMirror ||
challengeType === challengeTypes.BASEJUMP ||
challengeType === challengeTypes.ZIPLINE ||
challengeType === challengeTypes.VIDEO ||
challengeType === challengeTypes.STEP ||
challengeType === challengeTypes.HIKES
) {
common.editor = {};
return common;
}
var editor = CodeMirror.fromTextArea(
document.getElementById('codeEditor'),
{
lint: true,
lineNumbers: true,
mode: 'javascript',
theme: 'monokai',
runnable: true,
matchBrackets: true,
autoCloseBrackets: true,
scrollbarStyle: 'null',
lineWrapping: true,
gutters: ['CodeMirror-lint-markers']
}
);
editor.setSize('100%', 'auto');
common.editorExecute$ = new Subject();
common.editorKeyUp$ = Observable.fromEventPattern(
(handler) => editor.on('keyup', handler),
(handler) => editor.off('keyup', handler)
);
editor.setOption('extraKeys', {
Tab: function(cm) {
if (cm.somethingSelected()) {
cm.indentSelection('add');
} else {
var spaces = Array(cm.getOption('indentUnit') + 1).join(' ');
cm.replaceSelection(spaces);
}
},
'Shift-Tab': function(cm) {
if (cm.somethingSelected()) {
cm.indentSelection('subtract');
} else {
var spaces = Array(cm.getOption('indentUnit') + 1).join(' ');
cm.replaceSelection(spaces);
}
},
'Ctrl-Enter': function() {
common.editorExecute$.onNext();
return false;
},
'Cmd-Enter': function() {
common.editorExecute$.onNext();
return false;
},
'Ctrl-/': function(cm) {
cm.toggleComment();
},
'Cmd-/': function(cm) {
cm.toggleComment();
}
});
var info = editor.getScrollInfo();
var after = editor.charCoords({
line: editor.getCursor().line + 1,
ch: 0
}, 'local').top;
if (info.top + info.clientHeight < after) {
editor.scrollTo(null, after - info.clientHeight + 3);
}
if (emmetCodeMirror) {
emmetCodeMirror(
editor,
{
'Cmd-E': 'emmet.expand_abbreviation',
Tab: 'emmet.expand_abbreviation_with_tab',
Enter: 'emmet.insert_formatted_line_break_only'
}
);
}
common.init.push(function() {
let editorValue;
if (common.codeUri.isAlive()) {
editorValue = common.codeUri.parse();
} else {
editorValue = common.codeStorage.isAlive(common.challengeName) ?
common.codeStorage.getStoredValue(common.challengeName) :
common.seed;
}
editor.setValue(common.replaceSafeTags(editorValue));
editor.refresh();
});
common.editor = editor;
return common;
}(window));

View File

@@ -1,59 +0,0 @@
window.common = (function(global) {
const {
Rx: { Observable },
common = { init: [] }
} = global;
const detectFunctionCall = /function\s*?\(|function\s+\w+\s*?\(/gi;
const detectUnsafeJQ = /\$\s*?\(\s*?\$\s*?\)/gi;
const detectUnsafeConsoleCall = /if\s\(null\)\sconsole\.log\(1\);/gi;
const detectInComments = new RegExp(['\\/\\/.*?function.*?|',
'\\/\\*[\\s\\w\\W]*?function',
'[\\s\\w\\W]*?\\*\\/'].join(''), 'gi');
common.detectUnsafeCode$ = function detectUnsafeCode$(code) {
const openingComments = code.match(/\/\*/gi);
const closingComments = code.match(/\*\//gi);
// checks if the number of opening comments(/*) matches the number of
// closing comments(*/)
if (
openingComments &&
(
!closingComments ||
openingComments.length > closingComments.length
)
) {
return Observable.throw(
new Error('SyntaxError: Unfinished multi-line comment')
);
}
if (code.match(detectUnsafeJQ)) {
return Observable.throw(
new Error('Unsafe $($)')
);
}
if (
code.match(/function/g) &&
!code.match(detectFunctionCall) &&
!code.match(detectInComments)
) {
return Observable.throw(
new Error('SyntaxError: Unsafe or unfinished function declaration')
);
}
if (code.match(detectUnsafeConsoleCall)) {
return Observable.throw(
new Error('Invalid if (null) console.log(1); detected')
);
}
return Observable.just(code);
};
return common;
}(window));

View File

@@ -1,32 +0,0 @@
window.common = (function({ $, common = { init: [] }}) {
common.displayTestResults = function displayTestResults(data = [], down) {
$('#testSuite').children().remove();
data.forEach(({ err = false, text = '' }) => {
var iconClass = err ?
'"ion-close-circled big-error-icon"' :
'"ion-checkmark-circled big-success-icon"';
$('<div></div>').html(`
<div class='row'>
<div class='col-xs-2 text-center'>
<i class=${iconClass}></i>
</div>
<div class='col-xs-10 test-output'>
${text.split('message: ').pop().replace(/\'\);/g, '')}
</div>
<div class='ten-pixel-break'/>
</div>
`)
.appendTo($('#testSuite'));
});
if (down) {
$('#scroll-locker').animate(
{ scrollTop: $(document).height() }, 'slow'
);
}
return data;
};
return common;
}(window));

View File

@@ -1,177 +0,0 @@
$(document).ready(function() {
const common = window.common;
const { Observable } = window.Rx;
const {
addLoopProtect,
challengeName,
challengeType,
challengeTypes
} = common;
common.init.forEach(function(init) {
init($);
});
// only run if editor present
if (common.editor.getValue) {
const code$ = common.editorKeyUp$
.debounce(750)
.map(() => common.editor.getValue())
.distinctUntilChanged()
.shareReplay();
// update storage
code$.subscribe(
code => {
common.codeStorage.updateStorage(common.challengeName, code);
common.codeUri.querify(code);
},
err => console.error(err)
);
code$
// only run for HTML
.filter(() => common.challengeType === challengeTypes.HTML)
.flatMap(code => {
return common.detectUnsafeCode$(code)
.map(() => {
const combinedCode = common.head + code + common.tail;
return addLoopProtect(combinedCode);
})
.flatMap(code => common.updatePreview$(code))
.flatMap(() => common.checkPreview$({ code }))
.catch(err => Observable.just({ err }));
})
.subscribe(
({ err }) => {
if (err) {
console.error(err);
return common.updatePreview$(`
<h1>${err}</h1>
`).subscribe(() => {});
}
return null;
},
err => console.error(err)
);
}
common.resetBtn$
.doOnNext(() => {
common.editor.setValue(common.replaceSafeTags(common.seed));
})
.flatMap(() => {
return common.executeChallenge$()
.catch(err => Observable.just({ err }));
})
.subscribe(
({ err, output, originalCode, tests }) => {
if (err) {
console.error(err);
return common.updateOutputDisplay('' + err);
}
common.codeStorage.updateStorage(challengeName, originalCode);
common.codeUri.querify(originalCode);
common.displayTestResults(tests, true);
common.updateOutputDisplay(output);
return null;
},
(err) => {
if (err) {
console.error(err);
}
common.updateOutputDisplay('' + err);
}
);
Observable.merge(
common.editorExecute$,
common.submitBtn$
)
.flatMap(() => {
common.appendToOutputDisplay('\n// testing challenge...');
return common.executeChallenge$()
.map(({ tests, ...rest }) => {
const solved = tests.every(test => !test.err);
return { ...rest, tests, solved };
})
.catch(err => Observable.just({ err }));
})
.subscribe(
({ err, solved, output, tests }) => {
if (err) {
console.error(err);
if (common.challengeType === common.challengeTypes.HTML) {
return common.updatePreview$(`
<h1>${err}</h1>
`).first().subscribe(() => {});
}
return common.updateOutputDisplay('' + err);
}
common.updateOutputDisplay(output);
common.displayTestResults(tests, true);
if (solved) {
common.showCompletion();
}
return null;
},
({ err }) => {
console.error(err);
common.updateOutputDisplay('' + err);
}
);
// initial challenge run to populate tests
if (challengeType === challengeTypes.HTML) {
var $preview = $('#preview');
return Observable.fromCallback($preview.ready, $preview)()
.delay(500)
.flatMap(() => common.executeChallenge$())
.catch(err => Observable.just({ err }))
.subscribe(
({ err, tests }) => {
if (err) {
console.error(err);
if (common.challengeType === common.challengeTypes.HTML) {
return common.updatePreview$(`
<h1>${err}</h1>
`).subscribe(() => {});
}
return common.updateOutputDisplay('' + err);
}
common.displayTestResults(tests, false);
return null;
},
({ err }) => {
console.error(err);
}
);
}
if (
challengeType === challengeTypes.BONFIRE ||
challengeType === challengeTypes.JS
) {
return Observable.just({})
.delay(500)
.flatMap(() => common.executeChallenge$())
.catch(err => Observable.just({ err }))
.subscribe(
({ err, originalCode, tests }) => {
if (err) {
console.error(err);
return common.updateOutputDisplay('' + err);
}
common.codeStorage.updateStorage(challengeName, originalCode);
common.displayTestResults(tests, false);
return null;
},
(err) => {
console.error(err);
common.updateOutputDisplay('' + err);
}
);
}
return null;
});

View File

@@ -1,57 +0,0 @@
window.common = (function(global) {
const {
ga,
common = { init: [] }
} = global;
const {
addLoopProtect,
getJsFromHtml,
detectUnsafeCode$,
updatePreview$,
challengeType,
challengeTypes
} = common;
common.executeChallenge$ = function executeChallenge$() {
const code = common.editor.getValue();
const originalCode = code;
const head = common.arrayToNewLineString(common.head);
const tail = common.arrayToNewLineString(common.tail);
const combinedCode = head + code + tail;
ga('send', 'event', 'Challenge', 'ran-code', common.gaName);
// run checks for unsafe code
return detectUnsafeCode$(code)
// add head and tail and detect loops
.map(() => {
if (challengeType !== challengeTypes.HTML) {
return `<script>;${addLoopProtect(combinedCode)}/**/</script>`;
}
return addLoopProtect(combinedCode);
})
.flatMap(code => updatePreview$(code))
.flatMap(code => {
let output;
if (
challengeType === challengeTypes.HTML &&
common.hasJs(code)
) {
output = common.getJsOutput(getJsFromHtml(code));
} else if (challengeType !== challengeTypes.HTML) {
output = common.getJsOutput(addLoopProtect(combinedCode));
}
return common.runPreviewTests$({
tests: common.tests.slice(),
originalCode,
output
});
});
};
return common;
}(window));

View File

@@ -1,23 +0,0 @@
window.common = (function(global) {
const {
common = { init: [] },
document: doc
} = global;
common.getIframe = function getIframe(id = 'preview') {
let previewFrame = doc.getElementById(id);
// create and append a hidden preview frame
if (!previewFrame) {
previewFrame = doc.createElement('iframe');
previewFrame.id = id;
previewFrame.setAttribute('style', 'display: none');
doc.body.appendChild(previewFrame);
}
return previewFrame.contentDocument ||
previewFrame.contentWindow.document;
};
return common;
})(window);

View File

@@ -1,124 +0,0 @@
window.common = (function(global) {
// common namespace
// all classes should be stored here
// called at the beginning of dom ready
const {
Rx: { Disposable, Observable, config },
common = { init: [] }
} = global;
config.longStackSupport = true;
common.head = common.head || [];
common.tail = common.tail || [];
common.salt = Math.random();
common.challengeTypes = {
HTML: '0',
JS: '1',
VIDEO: '2',
ZIPLINE: '3',
BASEJUMP: '4',
BONFIRE: '5',
HIKES: '6',
STEP: '7'
};
common.arrayToNewLineString = function arrayToNewLineString(seedData) {
seedData = Array.isArray(seedData) ? seedData : [seedData];
return seedData.reduce(function(seed, line) {
return '' + seed + line + '\n';
}, '\n');
};
common.seed = common.arrayToNewLineString(common.challengeSeed);
common.replaceNoprotect = function replaceNoprotect(value) {
return value.replace(/noprotect/gi, '');
};
common.replaceScriptTags = function replaceScriptTags(value) {
return value
.replace(/<script>/gi, 'fccss')
.replace(/<\/script>/gi, 'fcces');
};
common.replaceSafeTags = function replaceSafeTags(value) {
return value
.replace(/fccss/gi, '<script>')
.replace(/fcces/gi, '</script>');
};
common.replaceFormActionAttr = function replaceFormAction(value) {
return value.replace(/<form[^>]*>/, function(val) {
return val.replace(/action(\s*?)=/, 'fccfaa$1=');
});
};
common.replaceFccfaaAttr = function replaceFccfaaAttr(value) {
return value.replace(/<form[^>]*>/, function(val) {
return val.replace(/fccfaa(\s*?)=/, 'action$1=');
});
};
common.scopejQuery = function scopejQuery(str) {
return str
.replace(/\$/gi, 'j$')
.replace(/document/gi, 'jdocument')
.replace(/jQuery/gi, 'jjQuery');
};
common.unScopeJQuery = function unScopeJQuery(str) {
return str
.replace(/j\$/gi, '$')
.replace(/jdocument/gi, 'document')
.replace(/jjQuery/gi, 'jQuery');
};
const commentRegex = /(\/\*[^(\*\/)]*\*\/)|([ \n]\/\/[^\n]*)/g;
common.removeComments = function removeComments(str) {
return str.replace(commentRegex, '');
};
const logRegex = /(console\.[\w]+\s*\(.*\;)/g;
common.removeLogs = function removeLogs(str) {
return str.replace(logRegex, '');
};
common.reassembleTest = function reassembleTest(code = '', { line, text }) {
var regexp = new RegExp('//' + line + common.salt);
return code.replace(regexp, text);
};
common.getScriptContent$ = function getScriptContent$(script) {
return Observable.create(function(observer) {
const jqXHR = $.get(script, null, null, 'text')
.success(data => {
observer.onNext(data);
observer.onCompleted();
})
.fail(e => observer.onError(e))
.always(() => observer.onCompleted());
return new Disposable(() => {
jqXHR.abort();
});
});
};
const openScript = /\<\s?script\s?\>/gi;
const closingScript = /\<\s?\/\s?script\s?\>/gi;
// detects if there is JavaScript in the first script tag
common.hasJs = function hasJs(code) {
return !!common.getJsFromHtml(code);
};
// grabs the content from the first script tag in the code
common.getJsFromHtml = function getJsFromHtml(code) {
// grab user javaScript
return (code.split(openScript)[1] || '').split(closingScript)[0] || '';
};
return common;
})(window);

View File

@@ -1,58 +0,0 @@
window.common = (function(global) {
const {
CodeMirror,
document: doc,
common = { init: [] }
} = global;
const { challengeTypes, challengeType = '0' } = common;
if (
!CodeMirror ||
challengeType !== challengeTypes.JS &&
challengeType !== challengeTypes.BONFIRE
) {
common.updateOutputDisplay = () => {};
common.appendToOutputDisplay = () => {};
return common;
}
var codeOutput = CodeMirror.fromTextArea(
doc.getElementById('codeOutput'),
{
lineNumbers: false,
mode: 'text',
theme: 'monokai',
readOnly: 'nocursor',
lineWrapping: true
}
);
codeOutput.setValue(`/**
* Your output will go here.
* Any console.log() - type
* statements will appear in
* your browser\'s DevTools
* JavaScript console as well.
*/`);
codeOutput.setSize('100%', '100%');
common.updateOutputDisplay = function updateOutputDisplay(str = '') {
if (typeof str === 'function') {
str = str.toString();
}
if (typeof str !== 'string') {
str = JSON.stringify(str);
}
codeOutput.setValue(str);
return str;
};
common.appendToOutputDisplay = function appendToOutputDisplay(str = '') {
codeOutput.setValue(codeOutput.getValue() + str);
return str;
};
return common;
}(window));

View File

@@ -1,132 +0,0 @@
window.common = (function({ common = { init: [] }}) {
common.lockTop = function lockTop() {
var magiVal;
if ($(window).width() >= 990) {
if ($('.editorScrollDiv').html()) {
magiVal = $(window).height() - $('.navbar').height();
if (magiVal < 0) {
magiVal = 0;
}
$('.editorScrollDiv').css('height', magiVal - 50 + 'px');
}
magiVal = $(window).height() - $('.navbar').height();
if (magiVal < 0) {
magiVal = 0;
}
$('.scroll-locker')
.css('min-height', $('.editorScrollDiv').height())
.css('height', magiVal - 50);
} else {
$('.editorScrollDiv').css('max-height', 500 + 'px');
$('.scroll-locker')
.css('position', 'inherit')
.css('top', 'inherit')
.css('width', '100%')
.css('max-height', '100%');
}
};
common.init.push(function($) {
// 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()) {
common.lockTop();
$(window).on('resize', function() {
common.lockTop();
});
$(window).on('scroll', function() {
common.lockTop();
});
}
var execInProgress = false;
// why is this not $???
document
.getElementById('scroll-locker')
.addEventListener(
'previewUpdateSpy',
function(e) {
if (execInProgress) {
return null;
}
execInProgress = true;
return 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
);
}
});
return common;
}(window));

View File

@@ -1,56 +0,0 @@
window.common = (function({ common = { init: [] } }) {
common.init.push(function($) {
$('#report-issue').on('click', function() {
var textMessage = [
'Challenge [',
(common.challengeName || window.location.pathname),
'](',
window.location.href,
') has an issue.\n',
'User Agent is: <code>',
navigator.userAgent,
'</code>.\n',
'Please describe how to reproduce this issue, and include ',
'links to screenshots if possible.\n\n'
].join('');
if (
common.editor &&
typeof common.editor.getValue === 'function' &&
common.editor.getValue().trim()
) {
var type;
switch (common.challengeType) {
case common.challengeTypes.HTML:
type = 'html';
break;
case common.challengeTypes.JS:
case common.challengeTypes.BONFIRE:
type = 'javascript';
break;
default:
type = '';
}
textMessage += [
'My code:\n```',
type,
'\n',
common.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'
);
});
});
return common;
}(window));

View File

@@ -1,40 +0,0 @@
window.common = (function(global) {
const {
Rx: { Observable },
chai,
common = { init: [] }
} = global;
common.runTests$ = function runTests$({
code,
originalCode,
userTests,
...rest
}) {
return Observable.from(userTests)
.map(function(test) {
/* eslint-disable no-unused-vars */
const assert = chai.assert;
const editor = { getValue() { return originalCode; }};
/* eslint-enable no-unused-vars */
try {
if (test) {
/* eslint-disable no-eval */
eval(common.reassembleTest(code, test));
/* eslint-enable no-eval */
}
} catch (e) {
test.err = e.message;
}
return test;
})
.toArray()
.map(tests => ({ ...rest, tests }));
};
return common;
}(window));

View File

@@ -1,90 +0,0 @@
window.common = (function(global) {
const {
$,
moment,
ga = (() => {}),
common = { init: [] }
} = global;
function submitChallengeHandler(e) {
e.preventDefault();
var solution = common.editor.getValue();
$('#submit-challenge')
.attr('disabled', 'true')
.removeClass('btn-primary')
.addClass('btn-warning disabled');
var $checkmarkContainer = $('#checkmark-container');
$checkmarkContainer.css({ height: $checkmarkContainer.innerHeight() });
$('#challenge-checkmark')
.addClass('zoomOutUp')
// .removeClass('zoomInDown')
.delay(1000)
.queue(function(next) {
$(this).replaceWith(
'<div id="challenge-spinner" ' +
'class="animated zoomInUp inner-circles-loader">' +
'submitting...</div>'
);
next();
});
let timezone = 'UTC';
try {
timezone = moment.tz.guess();
} catch (err) {
err.message = `
known bug, see: https://github.com/moment/moment-timezone/issues/294:
${err.message}
`;
console.error(err);
}
const data = JSON.stringify({
id: common.challengeId,
name: common.challengeName,
challengeType: +common.challengeType,
solution,
timezone
});
$.ajax({
url: '/completed-challenge/',
type: 'POST',
data,
contentType: 'application/json',
dataType: 'json'
})
.success(function(res) {
if (res) {
window.location =
'/challenges/next-challenge?id=' + common.challengeId;
}
})
.fail(function() {
window.location.replace(window.location.href);
});
}
common.showCompletion = function showCompletion() {
ga(
'send',
'event',
'Challenge',
'solved',
common.gaName,
true
);
$('#complete-courseware-dialog').modal('show');
$('#complete-courseware-dialog .modal-header').click();
$('#submit-challenge').off('click');
$('#submit-challenge').on('click', submitChallengeHandler);
};
return common;
}(window));

View File

@@ -1,200 +0,0 @@
window.common = (function({ $, common = { init: [] }}) {
const stepClass = '.challenge-step';
const prevBtnClass = '.challenge-step-btn-prev';
const nextBtnClass = '.challenge-step-btn-next';
const actionBtnClass = '.challenge-step-btn-action';
const finishBtnClass = '.challenge-step-btn-finish';
const submitBtnId = '#challenge-step-btn-submit';
const submitModalId = '#challenge-step-modal';
function getPreviousStep($challengeSteps) {
var $prevStep = false;
var prevStepIndex = 0;
$challengeSteps.each(function(index) {
var $step = $(this);
if (!$step.hasClass('hidden')) {
prevStepIndex = index - 1;
}
});
$prevStep = $challengeSteps[prevStepIndex];
return $prevStep;
}
function getNextStep($challengeSteps) {
var length = $challengeSteps.length;
var $nextStep = false;
var nextStepIndex = 0;
$challengeSteps.each(function(index) {
var $step = $(this);
if (
!$step.hasClass('hidden') &&
index + 1 !== length
) {
nextStepIndex = index + 1;
}
});
$nextStep = $challengeSteps[nextStepIndex];
return $nextStep;
}
function handlePrevStepClick(e) {
e.preventDefault();
var prevStep = getPreviousStep($(stepClass));
$(this)
.parent()
.parent()
.removeClass('slideInLeft slideInRight')
.addClass('animated fadeOutRight fast-animation')
.delay(250)
.queue(function(prev) {
$(this).addClass('hidden');
if (prevStep) {
$(prevStep)
.removeClass('hidden')
.removeClass('fadeOutLeft fadeOutRight')
.addClass('animated slideInLeft fast-animation')
.delay(500)
.queue(function(prev) {
prev();
});
}
prev();
});
}
function handleNextStepClick(e) {
e.preventDefault();
var nextStep = getNextStep($(stepClass));
$(this)
.parent()
.parent()
.removeClass('slideInRight slideInLeft')
.addClass('animated fadeOutLeft fast-animation')
.delay(250)
.queue(function(next) {
$(this).addClass('hidden');
if (nextStep) {
$(nextStep)
.removeClass('hidden')
.removeClass('fadeOutRight fadeOutLeft')
.addClass('animated slideInRight fast-animation')
.delay(500)
.queue(function(next) {
next();
});
}
next();
});
}
function handleActionClick(e) {
var props = common.challengeSeed[0] || { stepIndex: [] };
var $el = $(this);
var index = +$el.attr('id');
var propIndex = props.stepIndex.indexOf(index);
if (propIndex === -1) {
return $el.parent()
.find('.disabled')
.removeClass('disabled');
}
// an API action
// prevent link from opening
e.preventDefault();
var prop = props.properties[propIndex];
var api = props.apis[propIndex];
if (common[prop]) {
return $el.parent()
.find('.disabled')
.removeClass('disabled');
}
return $.post(api)
.done(function(data) {
// assume a boolean indicates passing
if (typeof data === 'boolean') {
return $el.parent()
.find('.disabled')
.removeClass('disabled');
}
// assume api returns string when fails
return $el.parent()
.find('.disabled')
.replaceWith('<p class="col-sm-4 col-xs-12">' + data + '</p>');
})
.fail(function() {
console.log('failed');
});
}
function handleFinishClick(e) {
e.preventDefault();
$(submitModalId).modal('show');
$(submitModalId + '.modal-header').click();
$(submitBtnId).click(handleSubmitClick);
}
function handleSubmitClick(e) {
e.preventDefault();
$('#submit-challenge')
.attr('disabled', 'true')
.removeClass('btn-primary')
.addClass('btn-warning disabled');
var $checkmarkContainer = $('#checkmark-container');
$checkmarkContainer.css({ height: $checkmarkContainer.innerHeight() });
$('#challenge-checkmark')
.addClass('zoomOutUp')
.delay(1000)
.queue(function(next) {
$(this).replaceWith(
'<div id="challenge-spinner" ' +
'class="animated zoomInUp inner-circles-loader">' +
'submitting...</div>'
);
next();
});
$.ajax({
url: '/completed-challenge/',
type: 'POST',
data: JSON.stringify({
id: common.challengeId,
name: common.challengeName,
challengeType: +common.challengeType
}),
contentType: 'application/json',
dataType: 'json'
})
.success(function(res) {
if (res) {
window.location =
'/challenges/next-challenge?id=' + common.challengeId;
}
})
.fail(function() {
window.location.replace(window.location.href);
});
}
common.init.push(function($) {
if (common.challengeType !== '7') {
return null;
}
$(prevBtnClass).click(handlePrevStepClick);
$(nextBtnClass).click(handleNextStepClick);
$(actionBtnClass).click(handleActionClick);
$(finishBtnClass).click(handleFinishClick);
return null;
});
return common;
}(window));

View File

@@ -1,154 +0,0 @@
window.common = (function(global) {
const {
Rx: { BehaviorSubject, Observable },
common = { init: [] }
} = global;
// the first script tag here is to proxy jQuery
// We use the same jQuery on the main window but we change the
// context to that of the iframe.
var libraryIncludes = `
<script>
window.loopProtect = parent.loopProtect;
window.__err = null;
window.loopProtect.hit = function(line) {
window.__err = new Error(
'Potential infinite loop at line ' +
line +
'. To disable loop protection, write:' +
' \\n\\/\\/ noprotect\\nas the first' +
' line. Beware that if you do have an infinite loop in your code' +
' this will crash your browser.'
);
};
</script>
<link
rel='stylesheet'
href='//cdnjs.cloudflare.com/ajax/libs/animate.css/3.2.0/animate.min.css'
/>
<link
rel='stylesheet'
href='//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css'
/>
<link
rel='stylesheet'
href='//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css'
/>
<style>
body { padding: 0px 3px 0px 3px; }
/* FORM RESET: */
textarea,
select,
input[type="date"],
input[type="datetime"],
input[type="datetime-local"],
input[type="email"],
input[type="month"],
input[type="number"],
input[type="password"],
input[type="search"],
input[type="tel"],
input[type="text"],
input[type="time"],
input[type="url"],
input[type="week"] {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
-webkit-background-clip: padding;
-moz-background-clip: padding;
background-clip:padding-box;
-webkit-border-radius:0;
-moz-border-radius:0;
-ms-border-radius:0;
-o-border-radius:0;
border-radius:0;
-webkit-appearance:none;
background-color:#fff;
color:#000;
outline:0;
margin:0;
padding:0;
text-align: left;
font-size:1em;
height: 1.8em;
vertical-align: middle;
}
select, select, select {
background:#fff
url('data:image/png;base64,\
R0lGODlhDQAEAIAAAAAAAP8A/yH5BAEHAAEAL\
AAAAAANAAQAAAILhA+hG5jMDpxvhgIAOw==');
background-repeat: no-repeat;
background-position: 97% center;
padding:0 25px 0 8px;
font-size: .875em;
}
// ! FORM RESET
</style>
`;
const codeDisabledError = `
<script>
window.__err = new Error('code has been disabled');
</script>
`;
const iFrameScript$ =
common.getScriptContent$('/js/iFrameScripts.js').shareReplay();
const jQueryScript$ = common.getScriptContent$(
'/bower_components/jquery/dist/jquery.js'
).shareReplay();
// behavior subject allways remembers the last value
// we use this to determine if runPreviewTest$ is defined
// and prime it with false
common.previewReady$ = new BehaviorSubject(false);
// These should be set up in the preview window
// if this error is seen it is because the function tried to run
// before the iframe has completely loaded
common.runPreviewTests$ =
common.checkPreview$ =
() => Observable.throw(new Error('Preview not fully loaded'));
common.updatePreview$ = function updatePreview$(code = '') {
const preview = common.getIframe('preview');
return Observable.combineLatest(
iFrameScript$,
jQueryScript$,
(iframe, jQuery) => ({
iframeScript: `<script>${iframe}</script>`,
jQuery: `<script>${jQuery}</script>`
})
)
.first()
.flatMap(({ iframeScript, jQuery }) => {
// we make sure to override the last value in the
// subject to false here.
common.previewReady$.onNext(false);
preview.open();
preview.write(
libraryIncludes +
jQuery +
(common.shouldRun() ? code : codeDisabledError) +
'<!-- -->' +
iframeScript
);
preview.close();
// now we filter false values and wait for the first true
return common.previewReady$
.filter(ready => ready)
.first()
// the delay here is to give code within the iframe
// control to run
.delay(400);
})
.map(() => code);
};
return common;
}(window));