]> _ Git - fluidbook-html5.git/commitdiff
#scorm : initialize work, generate imsmanifest
authorVincent Vanwaelscappel <vincent@cubedesigners.com>
Wed, 23 Mar 2016 10:45:48 +0000 (10:45 +0000)
committerVincent Vanwaelscappel <vincent@cubedesigners.com>
Wed, 23 Mar 2016 10:45:48 +0000 (10:45 +0000)
@2

_imsmanifest.xml [new file with mode: 0644]
js/libs/scorm/apiwrapper.js [new file with mode: 0644]
js/libs/scorm/scorm.js [new file with mode: 0644]

diff --git a/_imsmanifest.xml b/_imsmanifest.xml
new file mode 100644 (file)
index 0000000..dc87f9a
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<manifest xmlns="http://www.imsproject.org/xsd/imscp_rootv1p1p2" xmlns:imsmd="http://www.imsglobal.org/xsd/imsmd_rootv1p2p1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:adlcp="http://www.adlnet.org/xsd/adlcp_rootv1p2" identifier="MANIFEST-90878C16-EB60-D648-94ED-9651972B5F38" xsi:schemaLocation="http://www.imsproject.org/xsd/imscp_rootv1p1p2 imscp_rootv1p1p2.xsd http://www.imsglobal.org/xsd/imsmd_rootv1p2p1 imsmd_rootv1p2p1.xsd http://www.adlnet.org/xsd/adlcp_rootv1p2 adlcp_rootv1p2.xsd">\r
+    <metadata>\r
+        <schema>ADL SCORM</schema>\r
+        <schemaversion>1.2</schemaversion>\r
+    </metadata>\r
+    <organizations default="$scorm_org">\r
+        <organization identifier="$scorm_org" structure="hierarchical">\r
+            <title>$scorm_title</title>\r
+            <item identifier="$scorm_id" identifierref="$scorm_id" isvisible="true">\r
+                <title>$scorm_title</title>\r
+            </item>\r
+        </organization>\r
+    </organizations>\r
+    <resources>\r
+        <resource type="webcontent" adlcp:scormtype="sco" identifier="$scorm_id" href="index.html">\r
+            <file href="index.html"/>\r
+        </resource>\r
+    </resources>\r
+</manifest>
\ No newline at end of file
diff --git a/js/libs/scorm/apiwrapper.js b/js/libs/scorm/apiwrapper.js
new file mode 100644 (file)
index 0000000..6752f01
--- /dev/null
@@ -0,0 +1,506 @@
+/*******************************************************************************\r
+**\r
+** This software is provided "AS IS," without a warranty of any kind.  ALL\r
+** EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY\r
+** IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-\r
+** INFRINGEMENT, ARE HEREBY EXCLUDED.  PAUL BECKWITH AND HIS LICENSORS SHALL NOT BE LIABLE\r
+** FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR\r
+** DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES.  IN NO EVENT WILL PAUL BECKWITH OR ITS\r
+** LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,\r
+** INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER\r
+** CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF\r
+** OR INABILITY TO USE SOFTWARE, EVEN IF CTC  HAS BEEN ADVISED OF THE POSSIBILITY\r
+** OF SUCH DAMAGES.\r
+**    javascript:\r
+**          var result = doLMSInitialize();\r
+**          if (result != true) \r
+**          {\r
+**             // handle error\r
+**          }\r
+**\r
+*******************************************************************************/\r
+\r
+\r
+var _Debug = false;  // set this to false to turn debugging off\r
+                     // and get rid of those annoying alert boxes.\r
+\r
+// Define exception/error codes\r
+var _NoError = 0;\r
+var _GeneralException = 101;\r
+var _ServerBusy = 102;\r
+var _InvalidArgumentError = 201;\r
+var _ElementCannotHaveChildren = 202;\r
+var _ElementIsNotAnArray = 203;\r
+var _NotInitialized = 301;\r
+var _NotImplementedError = 401;\r
+var _InvalidSetValue = 402;\r
+var _ElementIsReadOnly = 403;\r
+var _ElementIsWriteOnly = 404;\r
+var _IncorrectDataType = 405;\r
+\r
+\r
+// local variable definitions\r
+var apiHandle = null;\r
+var API = null;\r
+var findAPITries = 0;\r
+\r
+\r
+/*******************************************************************************\r
+**\r
+** Function: doLMSInitialize()\r
+** Inputs:  None\r
+** Return:  CMIBoolean true if the initialization was successful, or\r
+**          CMIBoolean false if the initialization failed.\r
+**\r
+** Description:\r
+** Initialize communication with LMS by calling the LMSInitialize\r
+** function which will be implemented by the LMS.\r
+**\r
+*******************************************************************************/\r
+function doLMSInitialize()\r
+{\r
+   startTimer();\r
+\r
+   var api = getAPIHandle();\r
+   if (api == null)\r
+   {\r
+      alert("Unable to locate the LMS's API Implementation.\nLMSInitialize was not successful.");\r
+      return "false";\r
+   }\r
+\r
+   var result = api.LMSInitialize("");\r
+\r
+   if (result.toString() != "true")\r
+   {\r
+      var err = ErrorHandler();\r
+   }\r
+\r
+   return result.toString();\r
+}\r
+\r
+/*******************************************************************************\r
+**\r
+** Function doLMSFinish()\r
+** Inputs:  None\r
+** Return:  CMIBoolean true if successful\r
+**          CMIBoolean false if failed.\r
+**\r
+** Description:\r
+** Close communication with LMS by calling the LMSFinish\r
+** function which will be implemented by the LMS\r
+**\r
+*******************************************************************************/\r
+function doLMSFinish()\r
+{\r
+\r
+  setSessionTime();\r
+\r
+   var api = getAPIHandle();\r
+   if (api == null)\r
+   {\r
+      alert("Unable to locate the LMS's API Implementation.\nLMSFinish was not successful.");\r
+      return "false";\r
+   }\r
+   else\r
+   {\r
+      // call the LMSFinish function that should be implemented by the API\r
+\r
+      var result = api.LMSFinish("");\r
+      if (result.toString() != "true")\r
+      {\r
+         var err = ErrorHandler();\r
+      }\r
+\r
+   }\r
+\r
+   return result.toString();\r
+}\r
+\r
+/*******************************************************************************\r
+**\r
+** Function doLMSGetValue(name)\r
+** Inputs:  name - string representing the cmi data model defined category or\r
+**             element (e.g. cmi.core.student_id)\r
+** Return:  The value presently assigned by the LMS to the cmi data model\r
+**       element defined by the element or category identified by the name\r
+**       input value.\r
+**\r
+** Description:\r
+** Wraps the call to the LMS LMSGetValue method\r
+**\r
+*******************************************************************************/\r
+function doLMSGetValue(name)\r
+{\r
+   var api = getAPIHandle();\r
+   if (api == null)\r
+   {\r
+      alert("Unable to locate the LMS's API Implementation.\nLMSGetValue was not successful.");\r
+      return "";\r
+   }\r
+   else\r
+   {\r
+      var value = api.LMSGetValue(name);\r
+      var errCode = api.LMSGetLastError().toString();\r
+      if (errCode != _NoError)\r
+      {\r
+         // an error was encountered so display the error description\r
+         var errDescription = api.LMSGetErrorString(errCode);\r
+         alert("LMSGetValue("+name+") failed. \n"+ errDescription);\r
+         return "";\r
+      }\r
+      else\r
+      {\r
+         \r
+         return value.toString();\r
+      }\r
+   }\r
+}\r
+\r
+/*******************************************************************************\r
+**\r
+** Function doLMSSetValue(name, value)\r
+** Inputs:  name -string representing the data model defined category or element\r
+**          value -the value that the named element or category will be assigned\r
+** Return:  CMIBoolean true if successful\r
+**          CMIBoolean false if failed.\r
+**\r
+** Description:\r
+** Wraps the call to the LMS LMSSetValue function\r
+**\r
+*******************************************************************************/\r
+function doLMSSetValue(name, value)\r
+{\r
+   var api = getAPIHandle();\r
+   if (api == null)\r
+   {\r
+      alert("Unable to locate the LMS's API Implementation.\nLMSSetValue was not successful.");\r
+      return;\r
+   }\r
+   else\r
+   {\r
+      var result = api.LMSSetValue(name, value);\r
+      if (result.toString() != "true")\r
+      {\r
+         var err = ErrorHandler();\r
+      }\r
+   }\r
+\r
+   return;\r
+}\r
+\r
+/*******************************************************************************\r
+**\r
+** Function doLMSCommit()\r
+** Inputs:  None\r
+** Return:  None\r
+**\r
+** Description:\r
+** Call the LMSCommit function \r
+**\r
+*******************************************************************************/\r
+function doLMSCommit()\r
+{\r
+   var api = getAPIHandle();\r
+   if (api == null)\r
+   {\r
+      alert("Unable to locate the LMS's API Implementation.\nLMSCommit was not successful.");\r
+      return "false";\r
+   }\r
+   else\r
+   {\r
+      var result = api.LMSCommit("");\r
+      if (result != "true")\r
+      {\r
+         var err = ErrorHandler();\r
+      }\r
+   }\r
+\r
+   return result.toString();\r
+}\r
+\r
+/*******************************************************************************\r
+**\r
+** Function doLMSGetLastError()\r
+** Inputs:  None\r
+** Return:  The error code that was set by the last LMS function call\r
+**\r
+** Description:\r
+** Call the LMSGetLastError function \r
+**\r
+*******************************************************************************/\r
+function doLMSGetLastError()\r
+{\r
+   var api = getAPIHandle();\r
+   if (api == null)\r
+   {\r
+      alert("Unable to locate the LMS's API Implementation.\nLMSGetLastError was not successful.");\r
+      //since we can't get the error code from the LMS, return a general error\r
+      return _GeneralError;\r
+   }\r
+\r
+   return api.LMSGetLastError().toString();\r
+}\r
+\r
+/*******************************************************************************\r
+**\r
+** Function doLMSGetErrorString(errorCode)\r
+** Inputs:  errorCode - Error Code\r
+** Return:  The textual description that corresponds to the input error code\r
+**\r
+** Description:\r
+** Call the LMSGetErrorString function \r
+**\r
+********************************************************************************/\r
+function doLMSGetErrorString(errorCode)\r
+{\r
+   var api = getAPIHandle();\r
+   if (api == null)\r
+   {\r
+      alert("Unable to locate the LMS's API Implementation.\nLMSGetErrorString was not successful.");\r
+   }\r
+\r
+   return api.LMSGetErrorString(errorCode).toString();\r
+}\r
+\r
+/*******************************************************************************\r
+**\r
+** Function doLMSGetDiagnostic(errorCode)\r
+** Inputs:  errorCode - Error Code(integer format), or null\r
+** Return:  The vendor specific textual description that corresponds to the \r
+**          input error code\r
+**\r
+** Description:\r
+** Call the LMSGetDiagnostic function\r
+**\r
+*******************************************************************************/\r
+function doLMSGetDiagnostic(errorCode)\r
+{\r
+   var api = getAPIHandle();\r
+   if (api == null)\r
+   {\r
+      alert("Unable to locate the LMS's API Implementation.\nLMSGetDiagnostic was not successful.");\r
+   }\r
+\r
+   return api.LMSGetDiagnostic(errorCode).toString();\r
+}\r
+\r
+/*******************************************************************************\r
+**\r
+** Function LMSIsInitialized()\r
+** Inputs:  none\r
+** Return:  true if the LMS API is currently initialized, otherwise false\r
+**\r
+** Description:\r
+** Determines if the LMS API is currently initialized or not.\r
+**\r
+*******************************************************************************/\r
+function LMSIsInitialized()\r
+{\r
+   // there is no direct method for determining if the LMS API is initialized\r
+   // for example an LMSIsInitialized function defined on the API so we'll try\r
+   // a simple LMSGetValue and trap for the LMS Not Initialized Error\r
+\r
+   var api = getAPIHandle();\r
+   if (api == null)\r
+   {\r
+      alert("Unable to locate the LMS's API Implementation.\nLMSIsInitialized() failed.");\r
+      return false;\r
+   }\r
+   else\r
+   {\r
+      var value = api.LMSGetValue("cmi.core.student_name");\r
+      var errCode = api.LMSGetLastError().toString();\r
+      if (errCode == _NotInitialized)\r
+      {\r
+         return false;\r
+      }\r
+      else\r
+      {\r
+         return true;\r
+      }\r
+   }\r
+}\r
+\r
+/*******************************************************************************\r
+**\r
+** Function ErrorHandler()\r
+** Inputs:  None\r
+** Return:  The current value of the LMS Error Code\r
+**\r
+** Description:\r
+** Determines if an error was encountered by the previous API call\r
+** and if so, displays a message to the user.  If the error code\r
+** has associated text it is also displayed.\r
+**\r
+*******************************************************************************/\r
+function ErrorHandler()\r
+{\r
+   var api = getAPIHandle();\r
+   if (api == null)\r
+   {\r
+      alert("Unable to locate the LMS's API Implementation.\nCannot determine LMS error code.");\r
+      return;\r
+   }\r
+\r
+   // check for errors caused by or from the LMS\r
+   var errCode = api.LMSGetLastError().toString();\r
+   if (errCode != _NoError)\r
+   {\r
+      // an error was encountered so display the error description\r
+      var errDescription = api.LMSGetErrorString(errCode);\r
+\r
+      if (_Debug == true)\r
+      {\r
+         errDescription += "\n";\r
+         errDescription += api.LMSGetDiagnostic(null);\r
+         // by passing null to LMSGetDiagnostic, we get any available diagnostics\r
+         // on the previous error.\r
+      }\r
+\r
+      alert(errDescription);\r
+   }\r
+\r
+   return errCode;\r
+}\r
+\r
+/******************************************************************************\r
+**\r
+** Function getAPIHandle()\r
+** Inputs:  None\r
+** Return:  value contained by APIHandle\r
+**\r
+** Description:\r
+** Returns the handle to API object if it was previously set,\r
+** otherwise it returns null\r
+**\r
+*******************************************************************************/\r
+function getAPIHandle()\r
+{\r
+   if (apiHandle == null)\r
+   {\r
+      apiHandle = getAPI();\r
+   }\r
+\r
+   return apiHandle;\r
+}\r
+\r
+\r
+/*******************************************************************************\r
+**\r
+** Function findAPI(win)\r
+** Inputs:  win - a Window Object\r
+** Return:  If an API object is found, it's returned, otherwise null is returned\r
+**\r
+** Description:\r
+** This function looks for an object named API in parent and opener windows\r
+**\r
+*******************************************************************************/\r
+function findAPI(win)\r
+{\r
+   while ((win.API == null) && (win.parent != null) && (win.parent != win))\r
+   {\r
+      findAPITries++;\r
+      // Note: 7 is an arbitrary number, but should be more than sufficient\r
+      if (findAPITries > 7) \r
+      {\r
+         alert("Error finding API -- too deeply nested.");\r
+         return null;\r
+      }\r
+      \r
+      win = win.parent;\r
+\r
+   }\r
+   return win.API;\r
+}\r
+\r
+\r
+\r
+/*******************************************************************************\r
+**\r
+** Function getAPI()\r
+** Inputs:  none\r
+** Return:  If an API object is found, it's returned, otherwise null is returned\r
+**\r
+** Description:\r
+** This function looks for an object named API, first in the current window's \r
+** frame hierarchy and then, if necessary, in the current window's opener window\r
+** hierarchy (if there is an opener window).\r
+**\r
+*******************************************************************************/\r
+function getAPI()\r
+{\r
+   var theAPI = findAPI(window);\r
+   if ((theAPI == null) && (window.opener != null) && (typeof(window.opener) != "undefined"))\r
+   {\r
+      theAPI = findAPI(window.opener);\r
+   }\r
+   if (theAPI == null)\r
+   {\r
+      alert("Unable to find an API adapter");\r
+   }\r
+   return theAPI\r
+}\r
+\r
+\r
+var startTime;\r
+\r
+function startTimer()\r
+{\r
+   startTime = new Date().getTime();\r
+}\r
+\r
\r
+// call function right before LMSFinish\r
+function setSessionTime() {\r
+\r
+      var currentTime = new Date();\r
+\r
+      var endTime = currentTime.getTime()\r
+     \r
+      var calculatedTime = endTime-startTime;\r
+\r
+      var totalHours = Math.floor(calculatedTime/1000/60/60);\r
+\r
+      calculatedTime = calculatedTime - totalHours*1000*60*60\r
+\r
+      if ( totalHours < 1000 && totalHours > 99 ) {\r
+\r
+            totalHours = "0"+totalHours;\r
+\r
+      } else if ( totalHours < 100 && totalHours > 9 ) {\r
+\r
+            totalHours = "00"+totalHours;\r
+\r
+      } else if ( totalHours < 10 ) {\r
+\r
+            totalHours = "000"+totalHours;\r
+\r
+      }\r
+     \r
+\r
+      var totalMinutes = Math.floor(calculatedTime/1000/60);\r
+\r
+      calculatedTime = calculatedTime - totalMinutes*1000*60;\r
+\r
+      if ( totalMinutes < 10 ) {\r
+\r
+            totalMinutes = "0"+totalMinutes;\r
+\r
+      }\r
+     \r
+\r
+      var totalSeconds = Math.floor(calculatedTime/1000);\r
+\r
+      if ( totalSeconds < 10 ) {\r
+\r
+            totalSeconds = "0"+totalSeconds;\r
+\r
+      }\r
+\r
+      var sessionTime = totalHours+":"+totalMinutes+":"+totalSeconds;\r
+\r
+      doLMSSetValue("cmi.core.session_time", sessionTime);\r
+\r
+}\r
+\r
+\r
diff --git a/js/libs/scorm/scorm.js b/js/libs/scorm/scorm.js
new file mode 100644 (file)
index 0000000..b7a5d09
--- /dev/null
@@ -0,0 +1,19 @@
+SCORM = true;\r
+$(function () {\r
+    doLMSInitialize();\r
+\r
+    $(window).on('unload', function () {\r
+        doLMSFinish();\r
+    });\r
+});\r
+\r
+\r
+function getScormValue(elementName) {\r
+    var result = String(doLMSGetValue(elementName));\r
+    return result;\r
+}\r
+\r
+function setScormValue(elementName, value) {\r
+    var result = doLMSSetValue(elementName, value);\r
+    return result;\r
+}
\ No newline at end of file