diff options
Diffstat (limited to 'theme/javascript/core')
-rw-r--r-- | theme/javascript/core/exercise.js | 50 | ||||
-rw-r--r-- | theme/javascript/core/keyboard.js | 31 | ||||
-rw-r--r-- | theme/javascript/core/navigation.js | 17 | ||||
-rw-r--r-- | theme/javascript/core/progress.js | 66 | ||||
-rw-r--r-- | theme/javascript/core/sidebar.js | 42 | ||||
-rw-r--r-- | theme/javascript/core/state.js | 14 |
6 files changed, 220 insertions, 0 deletions
diff --git a/theme/javascript/core/exercise.js b/theme/javascript/core/exercise.js new file mode 100644 index 0000000..4163730 --- /dev/null +++ b/theme/javascript/core/exercise.js @@ -0,0 +1,50 @@ +define([ + "jQuery", + "utils/execute", + "utils/analytic", + "core/state" +], function($, execute, analytic, state){ + // Bind an exercise + var prepareExercise = function($exercise) { + var codeSolution = $exercise.find(".code-solution").text(); + var codeValidation = $exercise.find(".code-validation").text(); + + var editor = ace.edit($exercise.find(".editor").get(0)); + editor.setTheme("ace/theme/tomorrow"); + editor.getSession().setUseWorker(false); + editor.getSession().setMode("ace/mode/javascript"); + + // Submit: test code + $exercise.find(".action-submit").click(function(e) { + e.preventDefault(); + + analytic.track("exercise.submit"); + + execute(editor.getValue(), codeValidation, function(err, result) { + $exercise.toggleClass("return-error", err != null); + $exercise.toggleClass("return-success", err == null); + if (err) $exercise.find(".alert-danger").text(err.message || err); + }); + }); + + // Set solution + $exercise.find(".action-solution").click(function(e) { + e.preventDefault(); + + editor.setValue(codeSolution); + editor.gotoLine(0); + }); + }; + + // Prepare all exercise + var init = function() { + state().$book.find("section.exercise").each(function() { + prepareExercise($(this)); + }); + }; + + return { + init: init, + prepare: prepareExercise + }; +});
\ No newline at end of file diff --git a/theme/javascript/core/keyboard.js b/theme/javascript/core/keyboard.js new file mode 100644 index 0000000..05e939e --- /dev/null +++ b/theme/javascript/core/keyboard.js @@ -0,0 +1,31 @@ +define([ + "jQuery", + "Mousetrap", + "core/navigation", + "core/sidebar" +], function($, Mousetrap, navigation, sidebar){ + // Bind keyboard shortcuts + var init = function() { + // Next + Mousetrap.bind(['right'], function(e) { + navigation.goNext(); + return false; + }); + + // Prev + Mousetrap.bind(['left'], function(e) { + navigation.goPrev(); + return false; + }); + + // Toggle Summary + Mousetrap.bind(['s'], function(e) { + sidebar.toggle(); + return false; + }); + }; + + return { + init: init + }; +});
\ No newline at end of file diff --git a/theme/javascript/core/navigation.js b/theme/javascript/core/navigation.js new file mode 100644 index 0000000..bb3547c --- /dev/null +++ b/theme/javascript/core/navigation.js @@ -0,0 +1,17 @@ +define([ + "jQuery" +], function($) { + var goNext = function() { + var url = $("link[rel='next']").attr("href"); + if (url) location.href = url; + }; + var goPrev = function() { + var url = $("link[rel='prev']").attr("href"); + if (url) location.href = url; + }; + + return { + goNext: goNext, + goPrev: goPrev + }; +});
\ No newline at end of file diff --git a/theme/javascript/core/progress.js b/theme/javascript/core/progress.js new file mode 100644 index 0000000..755f111 --- /dev/null +++ b/theme/javascript/core/progress.js @@ -0,0 +1,66 @@ +define([ + "lodash", + "jQuery", + "utils/storage", + "core/state" +], function(_, $, storage, state) { + // Get current level + var getCurrentLevel = function() { + return state().level; + }; + + // Return all levels + var getLevels = function() { + var levels = $(".book-summary li[data-level]"); + return _.map(levels, function(level) { + return $(level).data("level").toString(); + }); + }; + + // Return a map chapter -> number (timestamp) + var getProgress = function() { + // Current level + var progress = storage.get("progress", {}); + + // Levels + var levels = getLevels(); + + _.each(levels, function(level) { + progress[level] = progress[level] || 0; + }); + + return progress; + }; + + // Change value of progress for a level + var markProgress = function(level, state) { + if (state == null) state = true; + + var progress = getProgress(); + progress[level] = state? Date.now() : 0; + + storage.set("progress", progress); + }; + + // Show progress + var showProgress = function() { + // Update progress + var progress = getProgress(); + var $summary = $(".book-summary"); + + _.each(progress, function(value, level) { + $summary.find("li[data-level='"+level+"']").toggleClass("done", value > 0); + }); + + // Mark current progress + markProgress(getCurrentLevel(), true); + }; + + return { + 'current': getCurrentLevel, + 'levels': getLevels, + 'get': getProgress, + 'mark': markProgress, + 'show': showProgress + }; +});
\ No newline at end of file diff --git a/theme/javascript/core/sidebar.js b/theme/javascript/core/sidebar.js new file mode 100644 index 0000000..717c2b7 --- /dev/null +++ b/theme/javascript/core/sidebar.js @@ -0,0 +1,42 @@ +define([ + "utils/storage", + "utils/platform", + "core/state" +], function(storage, platform, state) { + + // Toggle sidebar with or withour animation + var toggleSidebar = function(_state, animation) { + if (-state != null && isOpen() == _state) return; + if (animation == null) animation = true; + + var $book = state().$book; + $book.toggleClass("without-animation", !animation); + $book.toggleClass("with-summary", _state); + + storage.set("sidebar", isOpen()); + }; + + // Return true if sidebar is open + var isOpen = function() { + return state().$book.hasClass("with-summary"); + }; + + // Prepare sidebar: state and toggle button + var init = function() { + var $book = state().$book; + + // Toggle summary + $book.find(".book-header .toggle-summary").click(function(e) { + e.preventDefault(); + toggleSidebar(); + }); + + // Init last state if not mobile and not homepage + toggleSidebar(platform.isMobile ? false : storage.get("sidebar", true), false); + }; + + return { + init: init, + toggle: toggleSidebar + } +});
\ No newline at end of file diff --git a/theme/javascript/core/state.js b/theme/javascript/core/state.js new file mode 100644 index 0000000..fc67d7b --- /dev/null +++ b/theme/javascript/core/state.js @@ -0,0 +1,14 @@ +define([ + "jQuery" +], function() { + return function() { + var $book = $(".book"); + + return { + '$book': $book, + + 'githubId': $book.data("github"), + 'level': $book.data("level") + }; + }; +});
\ No newline at end of file |