From 91f3b77d4743731b6f0b2f282a592752565d7d74 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marko=20Pu=C5=A1nik?= <marko.pusnik@guru.si>
Date: Tue, 29 Sep 2015 16:06:11 +0200
Subject: made login as modal with arnesaai button + modals beautified;

---
 js/codeq/login.js | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

(limited to 'js')

diff --git a/js/codeq/login.js b/js/codeq/login.js
index f590acb..248e8c3 100644
--- a/js/codeq/login.js
+++ b/js/codeq/login.js
@@ -28,8 +28,9 @@
     };
     codeq.globalStateMachine.register('login',{
         'enter': function(){
+            $('#signed-in-title').html('');
             $("#submit").on('click', loginFun);
-            //$('#modalLogin').modal();
+            $('#modalLogIn').modal();
 
             $("#screen_login").css('display', '');
             $('#disabled').css('display', 'none');
@@ -37,6 +38,7 @@
         'exit' : function(){
             $("#submit").off('click', loginFun);
             $("#screen_login").css('display', 'none');
+            $('#signed-in-title').html('Signed in as '+$('#username').val());
             $("#password").val('');
         }
     });
-- 
cgit v1.2.1


From d657145124a601a9375b04a488ff2950f645f26d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ale=C5=A1=20Smodi=C5=A1?= <aless@guru.si>
Date: Tue, 29 Sep 2015 16:45:21 +0200
Subject: Correctly process hint_type and hint.

---
 js/codeq/hint.js    |  5 +++-
 js/codeq/problem.js | 70 +++++++++++++++++++++++++++++++++++------------------
 js/codeq/prolog.js  |  8 +++---
 js/codeq/python.js  |  8 +++---
 4 files changed, 59 insertions(+), 32 deletions(-)

(limited to 'js')

diff --git a/js/codeq/hint.js b/js/codeq/hint.js
index 1b97afc..0cb047a 100644
--- a/js/codeq/hint.js
+++ b/js/codeq/hint.js
@@ -7,7 +7,7 @@
     var firstCharacterPos = {'line': 0, 'ch': 0},
         sel_no_scroll = {'scroll': false};
 
-    codeq.makeHinter = function (jqHints, jqEditor, editor, trNamespace, hintDefsA, commonHintDefsA, planDef) {
+    codeq.makeHinter = function (jqHints, jqEditor, editor, trNamespace, problemDef, commonDef) {
         var hintCounter = 0, // for generating unique class-names
             hintCleaners = [],
             planIdx = 0,
@@ -134,6 +134,9 @@
         codeq.tr.registerDictionary(trNamespace, dictionary);
 
         // TODO: below is a temporary code to bridge the old implementation with the new data format
+        var hintDefsA = problemDef.hint,
+            commonHintDefsA = commonDef.hint,
+            planDef = problemDef.plan;
         if (planDef.sl) planDef = planDef.sl;
         else planDef = planDef.en || [];
         var hintDefs = {}, t1, t2, k;
diff --git a/js/codeq/problem.js b/js/codeq/problem.js
index 7ae54d8..d07e5fa 100644
--- a/js/codeq/problem.js
+++ b/js/codeq/problem.js
@@ -10,13 +10,23 @@
         // processed form, hint key -> translation language -> value
         // ================================================================================
 
+        defaultHintCondition = function (translation) {
+            // must contain at least one translation
+            var key;
+            if (!translation || typeof translation !== 'object') return false;
+            for (key in translation) {
+                if (!translation.hasOwnProperty(key)) continue;
+                return true;
+            }
+            return false;
+        },
         processHints = function (rawTranslations) {
             var defaultHint = {}, // here we put all the hints with their default translations
                 allHints = {}, // the result
                 allHintKeys = [],
                 tr, key, i, lang, hint, h, j;
             // find the default hint translations, they will form the basis of default hints
-            tr = chooseDefaultTranslation(rawTranslations, 'hint') || {};
+            tr = chooseDefaultTranslation(rawTranslations, 'hint', defaultHintCondition) || {};
             for (key in tr) { // copy the hints
                 if (!tr.hasOwnProperty(key)) continue;
                 defaultHint[key] = tr[key];
@@ -26,7 +36,7 @@
             for (i = langs.length - 1; i >= 0; i--) {
                 lang = langs[i];
                 tr = rawTranslations[lang];
-                if (!tr || !tr.hint) continue; // skip unavailable translations or translations with no hints
+                if (!tr || !defaultHintCondition(tr.hint)) continue; // skip unavailable translations or translations with no hints
                 hint = tr.hint;
                 for (key in hint) {
                     if (!hint.hasOwnProperty(key) || !hint[key]) continue;
@@ -37,22 +47,26 @@
                 }
             }
             // create all translations for hints
+            for (i = allHintKeys.length - 1; i >= 0; i--) {
+                allHints[allHintKeys[i]] = {}; // create keys with no translations, we'll fill them in the next loop
+            }
             for (i = langs.length - 1; i >= 0; i--) {
                 lang = langs[i];
                 tr = rawTranslations[lang];
                 // set up hints
-                if (!tr || !tr.hint) {
+                if (!tr || !defaultHintCondition(tr.hint)) {
                     // there's no hint in the current language, copy the default in its entirety
-                    allHints[lang] = defaultHint;
+                    for (j = allHintKeys.length - 1; j >= 0; j--) {
+                        key = allHintKeys[j];
+                        allHints[key][lang] = defaultHint[key];
+                    }
                 }
                 else {
                     // make a copy of all hints, using the default hint value where a hint value is missing
-                    hint = {};
-                    allHints[lang] = hint;
                     h = tr.hint;
-                    for (j = allHintKeys.length; j >= 0; j--) {
+                    for (j = allHintKeys.length - 1; j >= 0; j--) {
                         key = allHintKeys[j];
-                        hint[key] = h[key] || defaultHint[key];
+                        allHints[key][lang] = h[key] || defaultHint[key];
                     }
                 }
             }
@@ -64,9 +78,14 @@
         // processed form, hint key -> translation language -> value
         // ================================================================================
 
+        defaultPlanCondition = function (translation) {
+            // default plan must be non-empty
+            if (!translation || !(translation instanceof Array)) return false;
+            return translation.length > 0;
+        },
         processPlans = function (rawTranslations) {
             // find the default plan translation
-            var defaultPlan = chooseDefaultTranslation(rawTranslations, 'plan') || [],
+            var defaultPlan = chooseDefaultTranslation(rawTranslations, 'plan', defaultPlanCondition) || [],
                 allPlans = {}, // the result
                 i, lang, tr;
             // create all translations for plan
@@ -74,12 +93,12 @@
                 lang = langs[i];
                 tr = rawTranslations[lang];
                 // set up plan
-                if (!tr || !tr.plan) {
-                    // there's no plan in the current language, copy the default plan
-                    allPlans[lang] = defaultPlan;
+                if (tr && defaultPlanCondition(tr.plan)) {
+                    allPlans[lang] = tr.plan;
                 }
                 else {
-                    allPlans[lang] = tr.plan;
+                    // there's no plan in the current language, copy the default plan
+                    allPlans[lang] = defaultPlan;
                 }
             }
             return allPlans;
@@ -111,7 +130,7 @@
 
         /**
          * convert the input translations (arg0) for given keys (arg1..argN)
-         * so each keys holds all its translations for ever language
+         * so each keys holds all its translations for every language
          */
         convertTranslations = function () {
             var translations = arguments[0] || {},
@@ -187,7 +206,10 @@
                 'language': languageIdentifier, // 'prolog', 'python', ...
                 'html': html.join(''), // the DOM structure (without textual content), as HTML text
                 'refs': problemReferences, // array of problem info {g: group, p: problem, id: problem_id}, referenced from DOM <a> elements
-                'hints': processHints(rawTranslations) // hint translations: keyword -> lang -> value
+                'commonDef': {
+                    'hint': processHints(rawTranslations), // hint translations: keyword -> lang -> value
+                    'hint_type': data.hint_type || {}
+                }
             };
         },
 
@@ -218,7 +240,7 @@
                         .spread(function (userProblemData, generalProblemData) {
                             if (userProblemData.code !== 0) throw new Error('Failed to obtain user problem data, code: ' + userProblemData.code + ', message: ' + userProblemData.message);
                             if (!generalProblemData) throw new Error('General problem data is not defined');
-                            codeq.globalStateMachine.transition(language, generalProblemData, data.hints, userProblemData.solution);
+                            codeq.globalStateMachine.transition(language, generalProblemData, data.commonDef, userProblemData.solution);
                         })
                     )
                     .fail(function (reason) {
@@ -233,14 +255,15 @@
         // Problem definition processing
         // ================================================================================
 
-        chooseDefaultTranslation = function (rawTranslations, translationKey) {
+        chooseDefaultTranslation = function (rawTranslations, translationKey, condition) {
             var tr = rawTranslations.en, // try English as the default
-                lang;
-            if (tr && tr[translationKey]) return tr[translationKey];
-            for (lang in rawTranslations) { // find a translation with hints
-                if (!rawTranslations.hasOwnProperty(lang) || rawTranslations[lang]) continue;
+                lang, value;
+            if (typeof condition !== 'function') condition = function (x) { return !!x; };
+            if (tr && condition(tr[translationKey])) return tr[translationKey];
+            for (lang in rawTranslations) { // find a translation with content
+                if (!rawTranslations.hasOwnProperty(lang)) continue;
                 tr = rawTranslations[lang];
-                if (tr[translationKey]) return tr[translationKey];
+                if (tr && condition(tr[translationKey])) return tr[translationKey];
             }
             return null; // default must be chosen by the caller
         },
@@ -254,7 +277,8 @@
                 'id': rawData.id,
                 'translations': convertTranslations(rawTranslations, 'title', 'name', 'slug', 'description'), // GUI translations: keyword -> lang -> value
                 'hint': processHints(rawTranslations), // hint translations: keyword -> lang -> value
-                'plan': processPlans(rawTranslations) // plan translations: keyword -> lang -> value
+                'plan': processPlans(rawTranslations), // plan translations: keyword -> lang -> value
+                'hint_type': rawData.hint_type || {}
             };
         },
 
diff --git a/js/codeq/prolog.js b/js/codeq/prolog.js
index 87ac353..bcced1c 100644
--- a/js/codeq/prolog.js
+++ b/js/codeq/prolog.js
@@ -66,14 +66,14 @@
         };
     var prologHandler; //created when we enter the prolog state and destroyed once we leave it
     codeq.globalStateMachine.register('prolog', {
-        'enter': function (problemDef, commonHints, currentSolution) {
+        'enter': function (problemDef, commonDef, currentSolution) {
             $('#navigation-language').css('display', '');
             $('#navigation-problem').css('display', '');
             $("#navigation-prolog").addClass("active");
             $('#navigation-prolog').css('display', '');
 
             jqScreen.css('display', '');//we have to show the screen now so the code editor shows its initial values correctly
-            prologHandler = createPrologHandler(problemDef, commonHints, currentSolution);
+            prologHandler = createPrologHandler(problemDef, commonDef, currentSolution);
             subScreens = codeq.makeStateMachine(substates);
             subScreens.transition(jqDescription.data(stateNameTag));
 /*            Q.delay(100).then(function(){
@@ -253,7 +253,7 @@
      * @param {PrologTaskDef} info
      * @returns {{destroy: Function, processServerHints: Function}}
      */
-    createPrologHandler = function (problemDef, commonHints, currentSolution) {
+    createPrologHandler = function (problemDef, commonDef, currentSolution) {
         var //problem = info.problem,
             jqDescriptionContent = jqDescription.find('.description'),
             jqEditor = jqCode.find('.code_editor'),
@@ -264,7 +264,7 @@
             }),
             activityHandler = makeActivityHandler(editor, problemDef.id),
             terminal = makePrologTerminalHandler(jqTerminal, editor, problemDef.id, activityHandler),
-            hinter = codeq.makeHinter(jqHints, jqEditor, editor, 'prolog_hints', problemDef.hint, commonHints, problemDef.plan),
+            hinter = codeq.makeHinter(jqHints, jqEditor, editor, 'prolog_hints', problemDef, commonDef),
             commError = function (error) {
                 alert(error);
             };
diff --git a/js/codeq/python.js b/js/codeq/python.js
index e20fe06..8a9e92f 100644
--- a/js/codeq/python.js
+++ b/js/codeq/python.js
@@ -71,14 +71,14 @@
         };
     var pythonHandler; //created when we enter the python state and destroyed once we leave it
     codeq.globalStateMachine.register('python', {
-        'enter': function (problemDef, commonHints, currentSolution) {
+        'enter': function (problemDef, commonDef, currentSolution) {
             $('#navigation-language').css('display', '');
             $('#navigation-problem').css('display', '');
             $("#navigation-python").addClass("active");
             $('#navigation-python').css('display', '');
 
             jqScreen.css('display', '');//we have to show the screen now so the code editor shows its initial values correctly
-            pythonHandler = createPythonHandler(problemDef, commonHints, currentSolution);
+            pythonHandler = createPythonHandler(problemDef, commonDef, currentSolution);
             subScreens = codeq.makeStateMachine(substates);
             subScreens.transition(jqDescription.data(stateNameTag));
 /*            Q.delay(100).then(function(){
@@ -211,7 +211,7 @@
      * @param {PrologTaskDef} info
      * @returns {{destroy: Function, processServerHints: Function}}
      */
-    var createPythonHandler = function (problemDef, commonHints, currentSolution) {
+    var createPythonHandler = function (problemDef, commonDef, currentSolution) {
         var //problem = info.problem,
             jqDescriptionContent = jqDescription.find('.description'),
             jqEditor = jqCode.find('.code_editor'),
@@ -223,7 +223,7 @@
             }),
             activityHandler = makeActivityHandler(editor, problemDef.id),
             terminal = makePythonTerminalHandler(jqTerminal, editor, problemDef.id, activityHandler),
-            hinter = codeq.makeHinter(jqHints, jqEditor, editor, 'python_hints', problemDef.hint, commonHints, problemDef.plan),
+            hinter = codeq.makeHinter(jqHints, jqEditor, editor, 'python_hints', problemDef, commonDef),
             commError = function (error) {
                 alert(error);
             };
-- 
cgit v1.2.1


From 85e530fc7d2cf091734f0d126968d8c50defb65c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ale=C5=A1=20Smodi=C5=A1?= <aless@guru.si>
Date: Tue, 29 Sep 2015 17:14:49 +0200
Subject: Temporary hint fix: hints are shown in slovene only.

---
 js/codeq/hint.js | 69 ++++++++++++++++++++++++--------------------------------
 1 file changed, 30 insertions(+), 39 deletions(-)

(limited to 'js')

diff --git a/js/codeq/hint.js b/js/codeq/hint.js
index 0cb047a..d30f934 100644
--- a/js/codeq/hint.js
+++ b/js/codeq/hint.js
@@ -133,28 +133,15 @@
 
         codeq.tr.registerDictionary(trNamespace, dictionary);
 
-        // TODO: below is a temporary code to bridge the old implementation with the new data format
-        var hintDefsA = problemDef.hint,
-            commonHintDefsA = commonDef.hint,
-            planDef = problemDef.plan;
-        if (planDef.sl) planDef = planDef.sl;
-        else planDef = planDef.en || [];
-        var hintDefs = {}, t1, t2, k;
-        if (hintDefsA.sl) t1 = hintDefsA.sl;
-        else t1 = hintDefsA.en || {};
-        if (commonHintDefsA.sl) t2 = commonHintDefsA.sl;
-        else t2 = commonHintDefsA.en || {};
-        for (k in t2) {
-            if (!t2.hasOwnProperty(k)) continue;
-            hintDefs[k] = t2[k];
-        }
-        for (k in t1) {
-            if (!t1.hasOwnProperty(k)) continue;
-            hintDefs[k] = t1[k];
-        }
+        var hintProblemDefs = problemDef.hint_type,
+            hintCommonDefs = commonDef.hint_type,
+            hintProblemTr = problemDef.hint,
+            hintCommonTr = commonDef.hint,
+            planDef = problemDef.plan.sl;
 
         return {
-            /** Display the next "planning" hint and return whether there are
+            /**
+             * Display the next "planning" hint and return whether there are
              * any more available.
              */
             'planNext': function () {
@@ -173,46 +160,50 @@
              */
             'handle': function (serverHints) {
                 var n = serverHints.length,
-                    /** number */ i,
-                    /** ServerHint */ serverHint,
-                    /** HintDefinition */ hintDef,
-                    hintType, hintTemplate, t, fn, indices;
+                    i, serverHint, hintId, hintDef, hintContent, hintType, hintTemplate, t, fn, indices;
                 clearHints();
                 mainLoop:
                 for (i = 0; i < n; i++) {
                     serverHint = serverHints[i];
-                    hintDef = hintDefs[serverHint.id];
+                    hintId = serverHint.id;
+                    hintDef = hintProblemDefs[hintId];
+                    if (hintDef) {
+                        hintContent = hintProblemTr[hintId];
+                    }
+                    else {
+                        hintDef = hintCommonDefs[hintId];
+                        hintContent = hintCommonTr[hintId];
+                    }
                     if (!hintDef) {
-                        codeq.log.error('Undefined hint ' + serverHint.id);
+                        codeq.log.error('Undefined hint: ' + hintId);
+                        continue;
+                    }
+                    if (!hintContent) {
+                        codeq.log.error('Hint without content: ' + hintId);
                         continue;
                     }
                     if (serverHint.indices) {
                         indices = serverHint.indices;
                         for (i = 0; i < indices.length; i++) {
-                            hintDef = hintDef[indices[i]];
-                            if (!hintDef) {
-                                codeq.log.error('Undefined hint ' + serverHint.id + ' with indices ' + serverHint.indices);
+                            hintContent = hintContent[indices[i]];
+                            if (!hintContent) {
+                                codeq.log.error('Cannot reference hint ' + hintId + ' with indices ' + serverHint.indices);
                                 continue mainLoop;
                             }
                         }
                     }
+
                     t = typeof hintDef;
-                    if ((t === 'string') || (hintDef instanceof Array)) {
-                        hintType = 'static';
-                        hintTemplate = hintDef;
-                    }
-                    else if (t === 'object') {
-                        hintType = hintDef.type;
-                        hintTemplate = hintDef.message;
-                    }
+                    if (t === 'string') hintType = hintDef;
+                    else if ((t === 'object') && (hintDef !== null)) hintType = hintDef.type;
                     else {
-                        codeq.log.error('Unsupported hint definition: ' + t);
+                        codeq.log.error('Cannot determine type of hint ' + hintId + ' from: ' + hintDef);
                         continue;
                     }
 
                     fn = typeHandlers[hintType];
                     if (!fn) codeq.log.error('Unsupported hint type: ' + hintType);
-                    else fn(hintType, hintTemplate, serverHint);
+                    else fn(hintType, hintContent.sl, serverHint);
                 }
             },
 
-- 
cgit v1.2.1