summaryrefslogtreecommitdiffstats
path: root/theme/javascript/core
diff options
context:
space:
mode:
Diffstat (limited to 'theme/javascript/core')
-rw-r--r--theme/javascript/core/exercise.js50
-rw-r--r--theme/javascript/core/keyboard.js31
-rw-r--r--theme/javascript/core/navigation.js17
-rw-r--r--theme/javascript/core/progress.js66
-rw-r--r--theme/javascript/core/sidebar.js42
-rw-r--r--theme/javascript/core/state.js14
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