From: Vincent Vanwaelscappel Date: Wed, 23 Mar 2016 10:45:48 +0000 (+0000) Subject: #scorm : initialize work, generate imsmanifest X-Git-Url: http://git.cubedesigners.com/?a=commitdiff_plain;h=d045436bf1f2a7136639e517616f3613ac916a84;p=fluidbook-html5.git #scorm : initialize work, generate imsmanifest @2 --- diff --git a/_imsmanifest.xml b/_imsmanifest.xml new file mode 100644 index 00000000..dc87f9ab --- /dev/null +++ b/_imsmanifest.xml @@ -0,0 +1,20 @@ + + + + ADL SCORM + 1.2 + + + + $scorm_title + + $scorm_title + + + + + + + + + \ No newline at end of file diff --git a/js/libs/scorm/apiwrapper.js b/js/libs/scorm/apiwrapper.js new file mode 100644 index 00000000..6752f01b --- /dev/null +++ b/js/libs/scorm/apiwrapper.js @@ -0,0 +1,506 @@ +/******************************************************************************* +** +** This software is provided "AS IS," without a warranty of any kind. ALL +** EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY +** IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON- +** INFRINGEMENT, ARE HEREBY EXCLUDED. PAUL BECKWITH AND HIS LICENSORS SHALL NOT BE LIABLE +** FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR +** DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL PAUL BECKWITH OR ITS +** LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, +** INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER +** CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF +** OR INABILITY TO USE SOFTWARE, EVEN IF CTC HAS BEEN ADVISED OF THE POSSIBILITY +** OF SUCH DAMAGES. +** javascript: +** var result = doLMSInitialize(); +** if (result != true) +** { +** // handle error +** } +** +*******************************************************************************/ + + +var _Debug = false; // set this to false to turn debugging off + // and get rid of those annoying alert boxes. + +// Define exception/error codes +var _NoError = 0; +var _GeneralException = 101; +var _ServerBusy = 102; +var _InvalidArgumentError = 201; +var _ElementCannotHaveChildren = 202; +var _ElementIsNotAnArray = 203; +var _NotInitialized = 301; +var _NotImplementedError = 401; +var _InvalidSetValue = 402; +var _ElementIsReadOnly = 403; +var _ElementIsWriteOnly = 404; +var _IncorrectDataType = 405; + + +// local variable definitions +var apiHandle = null; +var API = null; +var findAPITries = 0; + + +/******************************************************************************* +** +** Function: doLMSInitialize() +** Inputs: None +** Return: CMIBoolean true if the initialization was successful, or +** CMIBoolean false if the initialization failed. +** +** Description: +** Initialize communication with LMS by calling the LMSInitialize +** function which will be implemented by the LMS. +** +*******************************************************************************/ +function doLMSInitialize() +{ + startTimer(); + + var api = getAPIHandle(); + if (api == null) + { + alert("Unable to locate the LMS's API Implementation.\nLMSInitialize was not successful."); + return "false"; + } + + var result = api.LMSInitialize(""); + + if (result.toString() != "true") + { + var err = ErrorHandler(); + } + + return result.toString(); +} + +/******************************************************************************* +** +** Function doLMSFinish() +** Inputs: None +** Return: CMIBoolean true if successful +** CMIBoolean false if failed. +** +** Description: +** Close communication with LMS by calling the LMSFinish +** function which will be implemented by the LMS +** +*******************************************************************************/ +function doLMSFinish() +{ + + setSessionTime(); + + var api = getAPIHandle(); + if (api == null) + { + alert("Unable to locate the LMS's API Implementation.\nLMSFinish was not successful."); + return "false"; + } + else + { + // call the LMSFinish function that should be implemented by the API + + var result = api.LMSFinish(""); + if (result.toString() != "true") + { + var err = ErrorHandler(); + } + + } + + return result.toString(); +} + +/******************************************************************************* +** +** Function doLMSGetValue(name) +** Inputs: name - string representing the cmi data model defined category or +** element (e.g. cmi.core.student_id) +** Return: The value presently assigned by the LMS to the cmi data model +** element defined by the element or category identified by the name +** input value. +** +** Description: +** Wraps the call to the LMS LMSGetValue method +** +*******************************************************************************/ +function doLMSGetValue(name) +{ + var api = getAPIHandle(); + if (api == null) + { + alert("Unable to locate the LMS's API Implementation.\nLMSGetValue was not successful."); + return ""; + } + else + { + var value = api.LMSGetValue(name); + var errCode = api.LMSGetLastError().toString(); + if (errCode != _NoError) + { + // an error was encountered so display the error description + var errDescription = api.LMSGetErrorString(errCode); + alert("LMSGetValue("+name+") failed. \n"+ errDescription); + return ""; + } + else + { + + return value.toString(); + } + } +} + +/******************************************************************************* +** +** Function doLMSSetValue(name, value) +** Inputs: name -string representing the data model defined category or element +** value -the value that the named element or category will be assigned +** Return: CMIBoolean true if successful +** CMIBoolean false if failed. +** +** Description: +** Wraps the call to the LMS LMSSetValue function +** +*******************************************************************************/ +function doLMSSetValue(name, value) +{ + var api = getAPIHandle(); + if (api == null) + { + alert("Unable to locate the LMS's API Implementation.\nLMSSetValue was not successful."); + return; + } + else + { + var result = api.LMSSetValue(name, value); + if (result.toString() != "true") + { + var err = ErrorHandler(); + } + } + + return; +} + +/******************************************************************************* +** +** Function doLMSCommit() +** Inputs: None +** Return: None +** +** Description: +** Call the LMSCommit function +** +*******************************************************************************/ +function doLMSCommit() +{ + var api = getAPIHandle(); + if (api == null) + { + alert("Unable to locate the LMS's API Implementation.\nLMSCommit was not successful."); + return "false"; + } + else + { + var result = api.LMSCommit(""); + if (result != "true") + { + var err = ErrorHandler(); + } + } + + return result.toString(); +} + +/******************************************************************************* +** +** Function doLMSGetLastError() +** Inputs: None +** Return: The error code that was set by the last LMS function call +** +** Description: +** Call the LMSGetLastError function +** +*******************************************************************************/ +function doLMSGetLastError() +{ + var api = getAPIHandle(); + if (api == null) + { + alert("Unable to locate the LMS's API Implementation.\nLMSGetLastError was not successful."); + //since we can't get the error code from the LMS, return a general error + return _GeneralError; + } + + return api.LMSGetLastError().toString(); +} + +/******************************************************************************* +** +** Function doLMSGetErrorString(errorCode) +** Inputs: errorCode - Error Code +** Return: The textual description that corresponds to the input error code +** +** Description: +** Call the LMSGetErrorString function +** +********************************************************************************/ +function doLMSGetErrorString(errorCode) +{ + var api = getAPIHandle(); + if (api == null) + { + alert("Unable to locate the LMS's API Implementation.\nLMSGetErrorString was not successful."); + } + + return api.LMSGetErrorString(errorCode).toString(); +} + +/******************************************************************************* +** +** Function doLMSGetDiagnostic(errorCode) +** Inputs: errorCode - Error Code(integer format), or null +** Return: The vendor specific textual description that corresponds to the +** input error code +** +** Description: +** Call the LMSGetDiagnostic function +** +*******************************************************************************/ +function doLMSGetDiagnostic(errorCode) +{ + var api = getAPIHandle(); + if (api == null) + { + alert("Unable to locate the LMS's API Implementation.\nLMSGetDiagnostic was not successful."); + } + + return api.LMSGetDiagnostic(errorCode).toString(); +} + +/******************************************************************************* +** +** Function LMSIsInitialized() +** Inputs: none +** Return: true if the LMS API is currently initialized, otherwise false +** +** Description: +** Determines if the LMS API is currently initialized or not. +** +*******************************************************************************/ +function LMSIsInitialized() +{ + // there is no direct method for determining if the LMS API is initialized + // for example an LMSIsInitialized function defined on the API so we'll try + // a simple LMSGetValue and trap for the LMS Not Initialized Error + + var api = getAPIHandle(); + if (api == null) + { + alert("Unable to locate the LMS's API Implementation.\nLMSIsInitialized() failed."); + return false; + } + else + { + var value = api.LMSGetValue("cmi.core.student_name"); + var errCode = api.LMSGetLastError().toString(); + if (errCode == _NotInitialized) + { + return false; + } + else + { + return true; + } + } +} + +/******************************************************************************* +** +** Function ErrorHandler() +** Inputs: None +** Return: The current value of the LMS Error Code +** +** Description: +** Determines if an error was encountered by the previous API call +** and if so, displays a message to the user. If the error code +** has associated text it is also displayed. +** +*******************************************************************************/ +function ErrorHandler() +{ + var api = getAPIHandle(); + if (api == null) + { + alert("Unable to locate the LMS's API Implementation.\nCannot determine LMS error code."); + return; + } + + // check for errors caused by or from the LMS + var errCode = api.LMSGetLastError().toString(); + if (errCode != _NoError) + { + // an error was encountered so display the error description + var errDescription = api.LMSGetErrorString(errCode); + + if (_Debug == true) + { + errDescription += "\n"; + errDescription += api.LMSGetDiagnostic(null); + // by passing null to LMSGetDiagnostic, we get any available diagnostics + // on the previous error. + } + + alert(errDescription); + } + + return errCode; +} + +/****************************************************************************** +** +** Function getAPIHandle() +** Inputs: None +** Return: value contained by APIHandle +** +** Description: +** Returns the handle to API object if it was previously set, +** otherwise it returns null +** +*******************************************************************************/ +function getAPIHandle() +{ + if (apiHandle == null) + { + apiHandle = getAPI(); + } + + return apiHandle; +} + + +/******************************************************************************* +** +** Function findAPI(win) +** Inputs: win - a Window Object +** Return: If an API object is found, it's returned, otherwise null is returned +** +** Description: +** This function looks for an object named API in parent and opener windows +** +*******************************************************************************/ +function findAPI(win) +{ + while ((win.API == null) && (win.parent != null) && (win.parent != win)) + { + findAPITries++; + // Note: 7 is an arbitrary number, but should be more than sufficient + if (findAPITries > 7) + { + alert("Error finding API -- too deeply nested."); + return null; + } + + win = win.parent; + + } + return win.API; +} + + + +/******************************************************************************* +** +** Function getAPI() +** Inputs: none +** Return: If an API object is found, it's returned, otherwise null is returned +** +** Description: +** This function looks for an object named API, first in the current window's +** frame hierarchy and then, if necessary, in the current window's opener window +** hierarchy (if there is an opener window). +** +*******************************************************************************/ +function getAPI() +{ + var theAPI = findAPI(window); + if ((theAPI == null) && (window.opener != null) && (typeof(window.opener) != "undefined")) + { + theAPI = findAPI(window.opener); + } + if (theAPI == null) + { + alert("Unable to find an API adapter"); + } + return theAPI +} + + +var startTime; + +function startTimer() +{ + startTime = new Date().getTime(); +} + + +// call function right before LMSFinish +function setSessionTime() { + + var currentTime = new Date(); + + var endTime = currentTime.getTime() + + var calculatedTime = endTime-startTime; + + 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; + + } + + var sessionTime = totalHours+":"+totalMinutes+":"+totalSeconds; + + doLMSSetValue("cmi.core.session_time", sessionTime); + +} + + diff --git a/js/libs/scorm/scorm.js b/js/libs/scorm/scorm.js new file mode 100644 index 00000000..b7a5d09d --- /dev/null +++ b/js/libs/scorm/scorm.js @@ -0,0 +1,19 @@ +SCORM = true; +$(function () { + doLMSInitialize(); + + $(window).on('unload', function () { + doLMSFinish(); + }); +}); + + +function getScormValue(elementName) { + var result = String(doLMSGetValue(elementName)); + return result; +} + +function setScormValue(elementName, value) { + var result = doLMSSetValue(elementName, value); + return result; +} \ No newline at end of file