From: Vincent Vanwaelscappel Date: Fri, 25 May 2018 15:22:46 +0000 (+0200) Subject: Merge branch 'master' into scorm2004 X-Git-Url: http://git.cubedesigners.com/?a=commitdiff_plain;h=a99ef48cdd76c9cbb847b6a53a034549a264ddb1;p=fluidbook-html5.git Merge branch 'master' into scorm2004 # Conflicts: # js/libs/scorm/scorm.js --- a99ef48cdd76c9cbb847b6a53a034549a264ddb1 diff --cc js/libs/scorm/scorm.js index c9ec652f,29ce4c96..635664c9 --- a/js/libs/scorm/scorm.js +++ b/js/libs/scorm/scorm.js @@@ -1,295 -1,57 +1,295 @@@ --SCORM = true; - SCORM_INITED = false; - SCORM_START_TIME = null; - SCORM_INTERACTION_TIMESTAMPS = []; - SCORM_CORRECT_ANSWERS = []; - SCORM_ID_TO_N = {}; - SCORM_WEIGHTING = 0; - SCORM_QUESTIONS = []; - SCORM_SUCCESS_STATUS = 'unknown'; - SCORM_SUCCESS_SCORE = 0; - - var _CMI12 = { - 'location': 'cmi.core.lesson_location', - 'status': "cmi.core.lesson_status", - 'session_time': 'cmi.core.session_time', - 'success_status': '', - }; - - var _CMI2004 = { - 'location': 'cmi.location', - 'status': 'cmi.completion_status', - 'session_time': 'cmi.session_time', - 'success_status': 'cmi.success_status', - } - --$(function () { -- if (fluidbook) { - initScorm(); - initScormEvents(); -- } else { -- $(document).on('fluidbookready', function () { - initScorm(); - initScormEvents(); -- }); -- } --}); - - function initScorm() { - if (SCORM_INITED) { - return; - } - SCORM_INITED = true; - pipwerks.SCORM.init(); - startScormTimer(); - initScormEvents(); - initScormInteractions(); - } - - function _cmi(key) { - var res = null; - switch (pipwerks.SCORM.version) { - case "1.2" : - res = _CMI12[key]; - break; - case '2004': - res = _CMI2004[key]; - break; - } - if (res == undefined || res == null) { - res = key; - } - return res; - } -- --function initScormEvents() { - initScorm(); - - doLMSInitialize(); -- $(window).on('unload', function () { - finishScorm(); - doLMSFinish(); -- }); -- - var currentPage = getScormValue('location'); - var currentStatus = getScormValue('cmi.core.lesson_status'); - if (currentStatus != 'passed' && currentStatus != 'completed') { - setScormValue('cmi.core.lesson_status', 'incomplete'); - } - - var currentPage = getScormValue('cmi.core.lesson_location'); -- try { -- if (currentPage != '') { -- var e = currentPage.split('_'); -- if (e.length == 2 && e[0] == 'page') { -- fluidbook.setCurrentPage(e[1]); -- } -- } -- } catch (err) { - console.log(err); - fb(err); -- } -- -- $(fluidbook).on('changePage', function (e, page) { - setScormValue('location', 'page_' + page); - setScormValue('cmi.core.lesson_location', 'page_' + page); - doLMSCommit(); -- }); - } - - function finishScorm() { - setSessionTime(); - pipwerks.SCORM.quit(); - } - - function startScormTimer() { - SCORM_START_TIME = new Date(); --} -- --function scormComplete() { - setScormValue('status', "completed"); - window.close(); - finishScorm(); - setScormValue("cmi.core.lesson_status", "completed"); - //window.open(location, '_self').close(); // IE 11 confirmation dialog bypass - top.close(); // This should work better for IE and in contexts where window isn't available - doLMSFinish(); --} -- --function getScormValue(elementName) { - var cmi = _cmi(elementName); - if (cmi == '') { - return null; - } - var result = pipwerks.SCORM.get(cmi); - var result = String(doLMSGetValue(elementName)); -- return result; --} -- --function setScormValue(elementName, value) { - var cmi = _cmi(elementName); - if (cmi == '') { - return false; - } - var result = pipwerks.SCORM.set(cmi, value); - pipwerks.SCORM.save(); - var result = doLMSSetValue(elementName, value); - doLMSCommit(); -- return result; - } - - function initScormInteractions() { - if (fluidbook.datas.scorm_quizdata === '') { - return; - } - var n = 0; - for (var sheet in fluidbook.datas.scorm_quizdata) { - var s = fluidbook.datas.scorm_quizdata[sheet]; - for (var l in s) { - if (l == 0) { - continue; - } - var line = s[l]; - if (line[1] === null || line[1] === '') { - continue; - } - defineScormInteraction(n, line[0], line[2], line[1], line[3], parseFloat(line[4])); - n++; - } - } - if (SCORM_WEIGHTING > 0) { - pipwerks.SCORM.set('cmi.score.min', '0'); - pipwerks.SCORM.set('cmi.score.max', SCORM_WEIGHTING); - SCORM_SUCCESS_SCORE = parseFloat(pipwerks.SCORM.get('cmi.scaled_passing_score')); - - updateInteractionsScore(); - } - } - - function defineScormInteraction(number, id, type, question, correct_response, weighting) { - - if (weighting === undefined) { - weighting = 1; - } - if (question === undefined) { - question = ''; - } - if (type === undefined) { - type = 'other'; - } - if (id === undefined) { - id = 'Q' + number; - } - - SCORM_QUESTIONS[number] = { - id: id, - question: question, - type: type, - correct_response: correct_response, - weighting: weighting, - timestamp: null, - result: false - }; - SCORM_ID_TO_N[id] = number; - - setScormValue('cmi.interactions.' + number + '.id', id); - setScormValue('cmi.interactions.' + number + '.description', question); - setScormValue('cmi.interactions.' + number + '.type', type); - setScormValue('cmi.interactions.' + number + '.correct_responses.0.pattern', correct_response); - setScormValue('cmi.interactions.' + number + '.weighting', weighting); - - SCORM_WEIGHTING += weighting; - } - - function getLearnerResponseById(id) { - return getScormValue('cmi.interactions.' + scormIdToN(id) + '.learner_response'); - } - - function scormIdToN(id) { - return SCORM_ID_TO_N[id]; - } - - function displayScormInteraction(id) { - var n = scormIdToN(id); - var now = new Date(); - if (SCORM_QUESTIONS[n].timestamp !== null) { - return; - } - SCORM_QUESTIONS[n].timestamp = now; - setScormValue('cmi.interactions.' + n + '.timestamp', dateToScormTime(now)); - } - - function answerScormInteraction(id, learner_response, result, set_latency) { - var n = scormIdToN(id); - var currentTime = Math.round(new Date().getTime() / 1000); - var latency = getScormTimeInterval(SCORM_QUESTIONS[n].timestamp, new Date()); - if (result === undefined) { - result = (learner_response === SCORM_QUESTIONS[n].correct_response); - } - - setScormValue('cmi.interactions.' + n + '.result', result ? 'correct' : 'incorrect'); - setScormValue('cmi.interactions.' + n + '.learner_response', learner_response); - setScormValue('cmi.interactions.' + n + '.latency', latency); - - updateInteractionsScore(); - } - - function updateInteractionsScore() { - var score = 0; - var answered = 0; - $.each(SCORM_QUESTIONS, function (n, q) { - var r = getScormValue('cmi.interactions.' + n + '.result'); - if (r == '') { - return; - } - answered++; - if (r == 'correct') { - score += q.weighting; - } - }); - - var scaled = score / SCORM_WEIGHTING; - - setScormValue('cmi.score.raw', score); - setScormValue('cmi.score.scaled', scaled); - var status = 'unknown' - if (answered > 0) { - if (scaled >= SCORM_SUCCESS_SCORE) { - status = 'passed'; - } else { - status = 'failed'; - } - } - setScormValue('cmi.success_status', status); - } - - function setSessionTime() { - var currentTime = new Date(); - var sessionTime; - - var endTime = currentTime.getTime() - var calculatedTime = endTime - SCORM_START_TIME; - - if (pipwerks.SCORM.version == '1.2') { - var totalHours = Math.floor(calculatedTime / 1000 / 60 / 60); - calculatedTime = calculatedTime - totalHours * 1000 * 60 * 60 - if (totalHours < 1000 && totalHours > 99) { - totalHours = "0" + totalHours; - } else if (totalHours < 100 && totalHours > 9) { - totalHours = "00" + totalHours; - } else if (totalHours < 10) { - totalHours = "000" + totalHours; - } - - var totalMinutes = Math.floor(calculatedTime / 1000 / 60); - calculatedTime = calculatedTime - totalMinutes * 1000 * 60; - if (totalMinutes < 10) { - totalMinutes = "0" + totalMinutes; - } - - var totalSeconds = Math.floor(calculatedTime / 1000); - if (totalSeconds < 10) { - totalSeconds = "0" + totalSeconds; - } - sessionTime = totalHours + ":" + totalMinutes + ":" + totalSeconds; - } else { - sessionTime = Math.round(calculatedTime / 1000); - } - setScormValue('session_time', sessionTime); - } - - function dateToScormTime(date) { - var res = date.toISOString(); - var e = res.split('.'); - e.pop(); - return res.join('.'); --} - - function getScormTimeInterval(start, end) { - var diff = Math.round((end.getTime() - start.getTime()) / 1000); - var h = Math.floor(diff / 3600); - diff = diff % 3600; - var m = Math.floor(diff / 60); - var s = diff % 60; - return 'PT' + h + 'H' + m + 'M' + s + 'S'; ++SCORM = true; ++SCORM_INITED = false; ++SCORM_START_TIME = null; ++SCORM_INTERACTION_TIMESTAMPS = []; ++SCORM_CORRECT_ANSWERS = []; ++SCORM_ID_TO_N = {}; ++SCORM_WEIGHTING = 0; ++SCORM_QUESTIONS = []; ++SCORM_SUCCESS_STATUS = 'unknown'; ++SCORM_SUCCESS_SCORE = 0; ++ ++var _CMI12 = { ++ 'location': 'cmi.core.lesson_location', ++ 'status': "cmi.core.lesson_status", ++ 'session_time': 'cmi.core.session_time', ++ 'success_status': '', ++}; ++ ++var _CMI2004 = { ++ 'location': 'cmi.location', ++ 'status': 'cmi.completion_status', ++ 'session_time': 'cmi.session_time', ++ 'success_status': 'cmi.success_status', ++} ++ ++$(function () { ++ if (fluidbook) { ++ initScorm(); ++ } else { ++ $(document).on('fluidbookready', function () { ++ initScorm(); ++ }); ++ } ++}); ++ ++function initScorm() { ++ if (SCORM_INITED) { ++ return; ++ } ++ SCORM_INITED = true; ++ pipwerks.SCORM.init(); ++ startScormTimer(); ++ initScormEvents(); ++ initScormInteractions(); ++} ++ ++function _cmi(key) { ++ var res = null; ++ switch (pipwerks.SCORM.version) { ++ case "1.2" : ++ res = _CMI12[key]; ++ break; ++ case '2004': ++ res = _CMI2004[key]; ++ break; ++ } ++ if (res == undefined || res == null) { ++ res = key; ++ } ++ return res; ++} ++ ++function initScormEvents() { ++ initScorm(); ++ ++ $(window).on('unload', function () { ++ finishScorm(); ++ }); ++ ++ var currentPage = getScormValue('location'); ++ try { ++ if (currentPage != '') { ++ var e = currentPage.split('_'); ++ if (e.length == 2 && e[0] == 'page') { ++ fluidbook.setCurrentPage(e[1]); ++ } ++ } ++ } catch (err) { ++ console.log(err); ++ } ++ ++ $(fluidbook).on('changePage', function (e, page) { ++ setScormValue('location', 'page_' + page); ++ }); ++} ++ ++function finishScorm() { ++ setSessionTime(); ++ pipwerks.SCORM.quit(); ++} ++ ++function startScormTimer() { ++ SCORM_START_TIME = new Date(); ++} ++ ++function scormComplete() { ++ setScormValue('status', "completed"); ++ window.close(); ++ finishScorm(); ++} ++ ++function getScormValue(elementName) { ++ var cmi = _cmi(elementName); ++ if (cmi == '') { ++ return null; ++ } ++ var result = pipwerks.SCORM.get(cmi); ++ return result; ++} ++ ++function setScormValue(elementName, value) { ++ var cmi = _cmi(elementName); ++ if (cmi == '') { ++ return false; ++ } ++ var result = pipwerks.SCORM.set(cmi, value); ++ pipwerks.SCORM.save(); ++ return result; ++} ++ ++function initScormInteractions() { ++ if (fluidbook.datas.scorm_quizdata === '') { ++ return; ++ } ++ var n = 0; ++ for (var sheet in fluidbook.datas.scorm_quizdata) { ++ var s = fluidbook.datas.scorm_quizdata[sheet]; ++ for (var l in s) { ++ if (l == 0) { ++ continue; ++ } ++ var line = s[l]; ++ if (line[1] === null || line[1] === '') { ++ continue; ++ } ++ defineScormInteraction(n, line[0], line[2], line[1], line[3], parseFloat(line[4])); ++ n++; ++ } ++ } ++ if (SCORM_WEIGHTING > 0) { ++ pipwerks.SCORM.set('cmi.score.min', '0'); ++ pipwerks.SCORM.set('cmi.score.max', SCORM_WEIGHTING); ++ SCORM_SUCCESS_SCORE = parseFloat(pipwerks.SCORM.get('cmi.scaled_passing_score')); ++ ++ updateInteractionsScore(); ++ } ++} ++ ++function defineScormInteraction(number, id, type, question, correct_response, weighting) { ++ ++ if (weighting === undefined) { ++ weighting = 1; ++ } ++ if (question === undefined) { ++ question = ''; ++ } ++ if (type === undefined) { ++ type = 'other'; ++ } ++ if (id === undefined) { ++ id = 'Q' + number; ++ } ++ ++ SCORM_QUESTIONS[number] = { ++ id: id, ++ question: question, ++ type: type, ++ correct_response: correct_response, ++ weighting: weighting, ++ timestamp: null, ++ result: false ++ }; ++ SCORM_ID_TO_N[id] = number; ++ ++ setScormValue('cmi.interactions.' + number + '.id', id); ++ setScormValue('cmi.interactions.' + number + '.description', question); ++ setScormValue('cmi.interactions.' + number + '.type', type); ++ setScormValue('cmi.interactions.' + number + '.correct_responses.0.pattern', correct_response); ++ setScormValue('cmi.interactions.' + number + '.weighting', weighting); ++ ++ SCORM_WEIGHTING += weighting; ++} ++ ++function getLearnerResponseById(id) { ++ return getScormValue('cmi.interactions.' + scormIdToN(id) + '.learner_response'); ++} ++ ++function scormIdToN(id) { ++ return SCORM_ID_TO_N[id]; ++} ++ ++function displayScormInteraction(id) { ++ var n = scormIdToN(id); ++ var now = new Date(); ++ if (SCORM_QUESTIONS[n].timestamp !== null) { ++ return; ++ } ++ SCORM_QUESTIONS[n].timestamp = now; ++ setScormValue('cmi.interactions.' + n + '.timestamp', dateToScormTime(now)); ++} ++ ++function answerScormInteraction(id, learner_response, result, set_latency) { ++ var n = scormIdToN(id); ++ var currentTime = Math.round(new Date().getTime() / 1000); ++ var latency = getScormTimeInterval(SCORM_QUESTIONS[n].timestamp, new Date()); ++ if (result === undefined) { ++ result = (learner_response === SCORM_QUESTIONS[n].correct_response); ++ } ++ ++ setScormValue('cmi.interactions.' + n + '.result', result ? 'correct' : 'incorrect'); ++ setScormValue('cmi.interactions.' + n + '.learner_response', learner_response); ++ setScormValue('cmi.interactions.' + n + '.latency', latency); ++ ++ updateInteractionsScore(); ++} ++ ++function updateInteractionsScore() { ++ var score = 0; ++ var answered = 0; ++ $.each(SCORM_QUESTIONS, function (n, q) { ++ var r = getScormValue('cmi.interactions.' + n + '.result'); ++ if (r == '') { ++ return; ++ } ++ answered++; ++ if (r == 'correct') { ++ score += q.weighting; ++ } ++ }); ++ ++ var scaled = score / SCORM_WEIGHTING; ++ ++ setScormValue('cmi.score.raw', score); ++ setScormValue('cmi.score.scaled', scaled); ++ var status = 'unknown' ++ if (answered > 0) { ++ if (scaled >= SCORM_SUCCESS_SCORE) { ++ status = 'passed'; ++ } else { ++ status = 'failed'; ++ } ++ } ++ setScormValue('cmi.success_status', status); ++} ++ ++function setSessionTime() { ++ var currentTime = new Date(); ++ var sessionTime; ++ ++ var endTime = currentTime.getTime() ++ var calculatedTime = endTime - SCORM_START_TIME; ++ ++ if (pipwerks.SCORM.version == '1.2') { ++ var totalHours = Math.floor(calculatedTime / 1000 / 60 / 60); ++ calculatedTime = calculatedTime - totalHours * 1000 * 60 * 60 ++ if (totalHours < 1000 && totalHours > 99) { ++ totalHours = "0" + totalHours; ++ } else if (totalHours < 100 && totalHours > 9) { ++ totalHours = "00" + totalHours; ++ } else if (totalHours < 10) { ++ totalHours = "000" + totalHours; ++ } ++ ++ var totalMinutes = Math.floor(calculatedTime / 1000 / 60); ++ calculatedTime = calculatedTime - totalMinutes * 1000 * 60; ++ if (totalMinutes < 10) { ++ totalMinutes = "0" + totalMinutes; ++ } ++ ++ var totalSeconds = Math.floor(calculatedTime / 1000); ++ if (totalSeconds < 10) { ++ totalSeconds = "0" + totalSeconds; ++ } ++ sessionTime = totalHours + ":" + totalMinutes + ":" + totalSeconds; ++ } else { ++ sessionTime = Math.round(calculatedTime / 1000); ++ } ++ setScormValue('session_time', sessionTime); ++} ++ ++function dateToScormTime(date) { ++ var res = date.toISOString(); ++ var e = res.split('.'); ++ e.pop(); ++ return res.join('.'); ++} ++ ++function getScormTimeInterval(start, end) { ++ var diff = Math.round((end.getTime() - start.getTime()) / 1000); ++ var h = Math.floor(diff / 3600); ++ diff = diff % 3600; ++ var m = Math.floor(diff / 60); ++ var s = diff % 60; ++ return 'PT' + h + 'H' + m + 'M' + s + 'S'; +}