|
|
var Backbone = require('backbone'); |
|
|
var jQuery = require('jquery'); |
|
|
var EventEmitter = require('events').EventEmitter; |
|
|
var React = require('react'); |
|
|
var ReactDOM = require('react-dom'); |
|
|
|
|
|
var util = require('../util'); |
|
|
var intl = require('../intl'); |
|
|
var LocaleStore = require('../stores/LocaleStore'); |
|
|
var LocaleActions = require('../actions/LocaleActions'); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Backbone.$ = jQuery; |
|
|
|
|
|
|
|
|
if (util.isBrowser()) { |
|
|
window.jQuery = jQuery; |
|
|
window.$ = jQuery; |
|
|
window.Raphael = require('raphael'); |
|
|
} |
|
|
|
|
|
var events = Object.assign( |
|
|
{}, |
|
|
EventEmitter.prototype, |
|
|
{ |
|
|
trigger: function() { |
|
|
|
|
|
this.emit.apply(this, arguments); |
|
|
} |
|
|
} |
|
|
); |
|
|
|
|
|
events.setMaxListeners(0); |
|
|
var commandUI; |
|
|
var sandbox; |
|
|
var eventBaton; |
|
|
var levelDropdown; |
|
|
|
|
|
|
|
|
|
|
|
var init = function() { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var Sandbox = require('../sandbox/').Sandbox; |
|
|
var EventBaton = require('../util/eventBaton').EventBaton; |
|
|
var LevelDropdownView = require('../views/levelDropdownView').LevelDropdownView; |
|
|
|
|
|
eventBaton = new EventBaton(); |
|
|
commandUI = new CommandUI(); |
|
|
sandbox = new Sandbox(); |
|
|
levelDropdown = new LevelDropdownView({ |
|
|
wait: true |
|
|
}); |
|
|
|
|
|
LocaleStore.subscribe(function() { |
|
|
if (LocaleStore.getLocale() !== LocaleStore.getDefaultLocale()) { |
|
|
intlRefresh(); |
|
|
} |
|
|
}); |
|
|
events.on('vcsModeChange', vcsModeRefresh); |
|
|
|
|
|
initRootEvents(eventBaton); |
|
|
initDemo(sandbox); |
|
|
|
|
|
window.LocaleStore = LocaleStore; |
|
|
window.LocaleActions = LocaleActions; |
|
|
window.intl = intl; |
|
|
}; |
|
|
|
|
|
var vcsModeRefresh = function(eventData) { |
|
|
if (!window.$) { return; } |
|
|
|
|
|
var mode = eventData.mode; |
|
|
var isGit = eventData.mode === 'git'; |
|
|
|
|
|
var displayMode = mode.slice(0, 1).toUpperCase() + mode.slice(1); |
|
|
var otherMode = (displayMode === 'Git') ? 'Hg' : 'Git'; |
|
|
var regex = new RegExp(otherMode, 'g'); |
|
|
|
|
|
document.title = intl.str('learn-git-branching').replace(regex, displayMode); |
|
|
$('span.vcs-mode-aware').each(function(i, el) { |
|
|
var text = $(el).text().replace(regex, displayMode); |
|
|
$(el).text(text); |
|
|
}); |
|
|
|
|
|
$('body').toggleClass('gitMode', isGit); |
|
|
$('body').toggleClass('hgMode', !isGit); |
|
|
}; |
|
|
|
|
|
var insertAlternateLinks = function(pageId) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var altLinks = LocaleStore.getSupportedLocales().map(function(langCode) { |
|
|
var url = "https://learngitbranching.js.org/?locale=" + langCode; |
|
|
return '<link rel="alternate" hreflang="'+langCode+'" href="' + url +'" />'; |
|
|
}); |
|
|
var defaultUrl = "https://learngitbranching.js.org/?locale=" + LocaleStore.getDefaultLocale(); |
|
|
altLinks.push('<link rel="alternate" hreflang="x-default" href="' + defaultUrl +'" />'); |
|
|
$('head').prepend(altLinks); |
|
|
|
|
|
}; |
|
|
|
|
|
var intlRefresh = function() { |
|
|
if (!window.$) { return; } |
|
|
var countryCode = LocaleStore.getLocale().split("_")[0]; |
|
|
$("html").attr('lang', countryCode); |
|
|
$("meta[http-equiv='content-language']").attr("content", countryCode); |
|
|
$('span.intl-aware').each(function(i, el) { |
|
|
var intl = require('../intl'); |
|
|
var key = $(el).attr('data-intl'); |
|
|
$(el).text(intl.str(key)); |
|
|
}); |
|
|
}; |
|
|
|
|
|
var initRootEvents = function(eventBaton) { |
|
|
|
|
|
var focusTextArea = function() { |
|
|
$('#commandTextField').focus(); |
|
|
}; |
|
|
focusTextArea(); |
|
|
|
|
|
$(window).focus(function(e) { |
|
|
eventBaton.trigger('windowFocus', e); |
|
|
}); |
|
|
$(document).click(function(e) { |
|
|
eventBaton.trigger('documentClick', e); |
|
|
}); |
|
|
$(document).bind('keydown', function(e) { |
|
|
eventBaton.trigger('docKeydown', e); |
|
|
}); |
|
|
$(document).bind('keyup', function(e) { |
|
|
eventBaton.trigger('docKeyup', e); |
|
|
}); |
|
|
$(window).on('resize', function(e) { |
|
|
events.trigger('resize', e); |
|
|
}); |
|
|
|
|
|
eventBaton.stealBaton('docKeydown', function() { }); |
|
|
eventBaton.stealBaton('docKeyup', function() { }); |
|
|
|
|
|
|
|
|
eventBaton.stealBaton('windowFocus', focusTextArea); |
|
|
eventBaton.stealBaton('documentClick', focusTextArea); |
|
|
|
|
|
|
|
|
|
|
|
var makeKeyListener = function(name) { |
|
|
return function() { |
|
|
var args = [name]; |
|
|
Array.prototype.slice.apply(arguments).forEach(function(arg) { |
|
|
args.push(arg); |
|
|
}); |
|
|
eventBaton.trigger.apply(eventBaton, args); |
|
|
}; |
|
|
}; |
|
|
|
|
|
$('#commandTextField').on('keydown', makeKeyListener('keydown')); |
|
|
$('#commandTextField').on('keyup', makeKeyListener('keyup')); |
|
|
$(window).trigger('resize'); |
|
|
}; |
|
|
|
|
|
var initDemo = function(sandbox) { |
|
|
var params = util.parseQueryString(window.location.href); |
|
|
|
|
|
|
|
|
|
|
|
var commands; |
|
|
if (/(iPhone|iPod|iPad).*AppleWebKit/i.test(navigator.userAgent) || /android/i.test(navigator.userAgent)) { |
|
|
sandbox.mainVis.customEvents.on('gitEngineReady', function() { |
|
|
eventBaton.trigger('commandSubmitted', 'mobile alert'); |
|
|
}); |
|
|
} |
|
|
|
|
|
if (params.hasOwnProperty('demo')) { |
|
|
commands = [ |
|
|
"git commit; git checkout -b bugFix C1; git commit; git merge main; git checkout main; git commit; git rebase bugFix;", |
|
|
"delay 1000; reset;", |
|
|
"level advanced1 --noFinishDialog --noStartCommand --noIntroDialog;", |
|
|
"delay 2000; show goal; delay 1000; hide goal;", |
|
|
"git checkout bugFix; git rebase main; git checkout side; git rebase bugFix;", |
|
|
"git checkout another; git rebase side; git rebase another main;", |
|
|
"help; levels" |
|
|
]; |
|
|
} else if (params.hasOwnProperty('hgdemo')) { |
|
|
commands = [ |
|
|
'importTreeNow {"branches":{"main":{"target":"C3","id":"main"},"feature":{"target":"C2","id":"feature"},"debug":{"target":"C4","id":"debug"}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C1"],"id":"C3"},"C4":{"parents":["C2"],"id":"C4"}},"HEAD":{"target":"feature","id":"HEAD"}}', |
|
|
'delay 1000', |
|
|
'git rebase main', |
|
|
'delay 1000', |
|
|
'undo', |
|
|
'hg book', |
|
|
'delay 1000', |
|
|
'hg rebase -d main' |
|
|
]; |
|
|
commands = commands.join(';#').split('#'); |
|
|
} else if (params.hasOwnProperty('hgdemo2')) { |
|
|
commands = [ |
|
|
'importTreeNow {"branches":{"main":{"target":"C3","id":"main"},"feature":{"target":"C2","id":"feature"},"debug":{"target":"C4","id":"debug"}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C1"],"id":"C3"},"C4":{"parents":["C2"],"id":"C4"}},"HEAD":{"target":"debug","id":"HEAD"}}', |
|
|
'delay 1000', |
|
|
'git rebase main', |
|
|
'delay 1000', |
|
|
'undo', |
|
|
'hg sum', |
|
|
'delay 1000', |
|
|
'hg rebase -d main' |
|
|
]; |
|
|
commands = commands.join(';#').split('#'); |
|
|
} else if (params.hasOwnProperty('remoteDemo')) { |
|
|
commands = [ |
|
|
'git clone', |
|
|
'git commit', |
|
|
'git fakeTeamwork', |
|
|
'git pull', |
|
|
'git push', |
|
|
'git commit', |
|
|
'git fakeTeamwork', |
|
|
'git pull --rebase', |
|
|
'git push', |
|
|
'levels' |
|
|
]; |
|
|
commands = commands.join(';#').split('#'); |
|
|
} else if (params.gist_level_id) { |
|
|
$.ajax({ |
|
|
url: 'https://api.github.com/gists/' + params.gist_level_id, |
|
|
type: 'GET', |
|
|
dataType: 'jsonp', |
|
|
success: function(response) { |
|
|
var data = response.data || {}; |
|
|
var files = data.files || {}; |
|
|
if (!Object.keys(files).length) { |
|
|
console.warn('no files found'); |
|
|
return; |
|
|
} |
|
|
var file = files[Object.keys(files)[0]]; |
|
|
if (!file.content) { |
|
|
console.warn('file empty'); |
|
|
} |
|
|
eventBaton.trigger( |
|
|
'commandSubmitted', |
|
|
'importLevelNow ' + escape(file.content) + '; clear; show goal;' |
|
|
); |
|
|
} |
|
|
}); |
|
|
} else if (!params.hasOwnProperty('NODEMO')) { |
|
|
commands = [ |
|
|
"help;", |
|
|
"levels" |
|
|
]; |
|
|
} |
|
|
if (params.hasOwnProperty('STARTREACT')) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
if (commands) { |
|
|
sandbox.mainVis.customEvents.on('gitEngineReady', function() { |
|
|
eventBaton.trigger('commandSubmitted', commands.join('')); |
|
|
}); |
|
|
} |
|
|
|
|
|
if (params.locale !== undefined && params.locale.length) { |
|
|
LocaleActions.changeLocaleFromURI(params.locale); |
|
|
} else { |
|
|
tryLocaleDetect(); |
|
|
} |
|
|
|
|
|
insertAlternateLinks(); |
|
|
|
|
|
if (params.command) { |
|
|
var command = unescape(params.command); |
|
|
sandbox.mainVis.customEvents.on('gitEngineReady', function() { |
|
|
eventBaton.trigger('commandSubmitted', command); |
|
|
}); |
|
|
} |
|
|
|
|
|
}; |
|
|
|
|
|
function tryLocaleDetect() { |
|
|
|
|
|
changeLocaleFromHeaders(navigator.language || navigator.browserLanguage); |
|
|
} |
|
|
|
|
|
function changeLocaleFromHeaders(langString) { |
|
|
LocaleActions.changeLocaleFromHeader(langString); |
|
|
} |
|
|
|
|
|
if (require('../util').isBrowser()) { |
|
|
|
|
|
$(document).ready(init); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function CommandUI() { |
|
|
Backbone.$ = $; |
|
|
var Views = require('../views'); |
|
|
var Collections = require('../models/collections'); |
|
|
var CommandViews = require('../views/commandViews'); |
|
|
var CommandHistoryView = require('../react_views/CommandHistoryView.jsx'); |
|
|
var MainHelperBarView = require('../react_views/MainHelperBarView.jsx'); |
|
|
|
|
|
this.commandCollection = new Collections.CommandCollection(); |
|
|
this.commandBuffer = new Collections.CommandBuffer({ |
|
|
collection: this.commandCollection |
|
|
}); |
|
|
|
|
|
this.commandPromptView = new CommandViews.CommandPromptView({ |
|
|
el: $('#commandLineBar') |
|
|
}); |
|
|
|
|
|
ReactDOM.render( |
|
|
React.createElement(MainHelperBarView), |
|
|
document.getElementById('helperBarMount') |
|
|
); |
|
|
ReactDOM.render( |
|
|
React.createElement( |
|
|
CommandHistoryView, |
|
|
{ commandCollection: this.commandCollection } |
|
|
), |
|
|
document.getElementById('commandDisplay') |
|
|
); |
|
|
} |
|
|
|
|
|
exports.getEvents = function() { |
|
|
return events; |
|
|
}; |
|
|
|
|
|
exports.getSandbox = function() { |
|
|
return sandbox; |
|
|
}; |
|
|
|
|
|
exports.getEventBaton = function() { |
|
|
return eventBaton; |
|
|
}; |
|
|
|
|
|
exports.getCommandUI = function() { |
|
|
return commandUI; |
|
|
}; |
|
|
|
|
|
exports.getLevelDropdown = function() { |
|
|
return levelDropdown; |
|
|
}; |
|
|
|
|
|
exports.init = init; |
|
|
|