Adding new selfReportSessionTime setting

This commit is contained in:
Jonathan Putney
2020-06-26 14:50:33 -04:00
parent aa03f6affb
commit ca94ee9fb5
12 changed files with 643 additions and 500 deletions

View File

@@ -23,6 +23,7 @@ export default class BaseAPI {
commitRequestDataType: 'application/json;charset=UTF-8',
autoProgress: false,
logLevel: global_constants.LOG_LEVEL_ERROR,
selfReportSessionTime: false,
responseHandler: function(xhr) {
let result;
if (typeof xhr !== 'undefined') {
@@ -62,6 +63,7 @@ export default class BaseAPI {
this.settings = settings;
this.apiLogLevel = this.settings.logLevel;
this.selfReportSessionTime = this.settings.selfReportSessionTime;
}
/**
@@ -82,6 +84,10 @@ export default class BaseAPI {
} else if (this.isTerminated()) {
this.throwSCORMError(this.#error_codes.TERMINATED, terminationMessage);
} else {
if (this.selfReportSessionTime) {
this.cmi.setStartTime();
}
this.currentState = global_constants.STATE_INITIALIZED;
this.lastErrorCode = 0;
returnValue = global_constants.SCORM_TRUE;
@@ -132,7 +138,7 @@ export default class BaseAPI {
this.throwSCORMError(result.errorCode);
}
returnValue = result.result ?
result.result : global_constants.SCORM_FALSE;
result.result : global_constants.SCORM_FALSE;
if (checkTerminated) this.lastErrorCode = 0;
@@ -256,7 +262,7 @@ export default class BaseAPI {
this.throwSCORMError(result.errorCode);
}
returnValue = result.result ?
result.result : global_constants.SCORM_FALSE;
result.result : global_constants.SCORM_FALSE;
this.apiLog(callbackName, 'HttpRequest', ' Result: ' + returnValue,
global_constants.LOG_LEVEL_DEBUG);
@@ -452,9 +458,9 @@ export default class BaseAPI {
*/
_checkObjectHasProperty(refObject, attribute: String) {
return Object.hasOwnProperty.call(refObject, attribute) ||
Object.getOwnPropertyDescriptor(
Object.getPrototypeOf(refObject), attribute) ||
(attribute in refObject);
Object.getOwnPropertyDescriptor(
Object.getPrototypeOf(refObject), attribute) ||
(attribute in refObject);
}
/**
@@ -518,15 +524,15 @@ export default class BaseAPI {
const invalidErrorMessage = `The data model element passed to ${methodName} (${CMIElement}) is not a valid SCORM data model element.`;
const invalidErrorCode = scorm2004 ?
this.#error_codes.UNDEFINED_DATA_MODEL :
this.#error_codes.GENERAL;
this.#error_codes.UNDEFINED_DATA_MODEL :
this.#error_codes.GENERAL;
for (let i = 0; i < structure.length; i++) {
const attribute = structure[i];
if (i === structure.length - 1) {
if (scorm2004 && (attribute.substr(0, 8) === '{target=') &&
(typeof refObject._isTargetValid == 'function')) {
(typeof refObject._isTargetValid == 'function')) {
this.throwSCORMError(this.#error_codes.READ_ONLY_ELEMENT);
} else if (!this._checkObjectHasProperty(refObject, attribute)) {
this.throwSCORMError(invalidErrorCode, invalidErrorMessage);
@@ -632,8 +638,8 @@ export default class BaseAPI {
const uninitializedErrorMessage = `The data model element passed to ${methodName} (${CMIElement}) has not been initialized.`;
const invalidErrorMessage = `The data model element passed to ${methodName} (${CMIElement}) is not a valid SCORM data model element.`;
const invalidErrorCode = scorm2004 ?
this.#error_codes.UNDEFINED_DATA_MODEL :
this.#error_codes.GENERAL;
this.#error_codes.UNDEFINED_DATA_MODEL :
this.#error_codes.GENERAL;
for (let i = 0; i < structure.length; i++) {
attribute = structure[i];
@@ -647,7 +653,7 @@ export default class BaseAPI {
}
} else {
if ((String(attribute).substr(0, 8) === '{target=') &&
(typeof refObject._isTargetValid == 'function')) {
(typeof refObject._isTargetValid == 'function')) {
const target = String(attribute).
substr(8, String(attribute).length - 9);
return refObject._isTargetValid(target);
@@ -767,8 +773,11 @@ export default class BaseAPI {
const functionsMatch = listener.functionName === functionName;
const listenerHasCMIElement = !!listener.CMIElement;
let CMIElementsMatch = false;
if (CMIElement && listener.CMIElement && listener.CMIElement.substring(listener.CMIElement.length - 1) === '*') {
CMIElementsMatch = CMIElement.indexOf(listener.CMIElement.substring(0, listener.CMIElement.length - 1)) === 0;
if (CMIElement && listener.CMIElement &&
listener.CMIElement.substring(listener.CMIElement.length - 1) ===
'*') {
CMIElementsMatch = CMIElement.indexOf(listener.CMIElement.substring(0,
listener.CMIElement.length - 1)) === 0;
} else {
CMIElementsMatch = listener.CMIElement === CMIElement;
}

View File

@@ -62,6 +62,7 @@ export function checkValidRange(
export class BaseCMI {
jsonString = false;
#initialized = false;
#start_time;
/**
* Constructor for BaseCMI, just marks the class as abstract
@@ -80,12 +81,28 @@ export class BaseCMI {
return this.#initialized;
}
/**
* Getter for #start_time
* @return {Number}
*/
get start_time() {
return this.#start_time;
}
/**
* Called when the API has been initialized after the CMI has been created
*/
initialize() {
this.#initialized = true;
}
/**
* Called when the player should override the 'session_time' provided by
* the module
*/
setStartTime() {
this.#start_time = new Date().getTime();
}
}
/**

View File

@@ -11,6 +11,7 @@ import ErrorCodes from '../constants/error_codes';
import Regex from '../constants/regex';
import {ValidationError} from '../exceptions';
import * as Utilities from '../utilities';
import * as Util from '../utilities';
const scorm12_constants = APIConstants.scorm12;
const scorm12_regex = Regex.scorm12;
@@ -254,7 +255,7 @@ export class CMI extends BaseCMI {
* @return {string}
*/
getCurrentTotalTime() {
return this.core.getCurrentTotalTime();
return this.core.getCurrentTotalTime(this.start_time);
}
}
@@ -508,13 +509,21 @@ class CMICore extends BaseCMI {
/**
* Adds the current session time to the existing total time.
*
* @param {Number} start_time
* @return {string}
*/
getCurrentTotalTime() {
getCurrentTotalTime(start_time: Number) {
let sessionTime = this.#session_time;
const startTime = start_time;
if (typeof startTime !== 'undefined' || startTime === null) {
const seconds = new Date().getTime() - startTime;
sessionTime = Util.getSecondsAsHHMMSS(seconds / 1000);
}
return Utilities.addHHMMSSTimeStrings(
this.#total_time,
this.#session_time,
sessionTime,
new RegExp(scorm12_regex.CMITimespan),
);
}

View File

@@ -431,7 +431,8 @@ export class CMI extends BaseCMI {
* @param {string} suspend_data
*/
set suspend_data(suspend_data) {
if (check2004ValidFormat(suspend_data, scorm2004_regex.CMIString64000, true)) {
if (check2004ValidFormat(suspend_data, scorm2004_regex.CMIString64000,
true)) {
this.#suspend_data = suspend_data;
}
}
@@ -476,9 +477,17 @@ export class CMI extends BaseCMI {
* @return {string} ISO8601 Duration
*/
getCurrentTotalTime() {
let sessionTime = this.#session_time;
const startTime = this.start_time;
if (typeof startTime !== 'undefined' || startTime === null) {
const seconds = new Date().getTime() - startTime;
sessionTime = Util.getSecondsAsISODuration(seconds / 1000);
}
return Util.addTwoDurations(
this.#total_time,
this.#session_time,
sessionTime,
scorm2004_regex.CMITimespan,
);
}
@@ -966,7 +975,8 @@ export class CMIInteractionsObject extends BaseCMI {
* @param {string} description
*/
set description(description) {
if (check2004ValidFormat(description, scorm2004_regex.CMILangString250, true)) {
if (check2004ValidFormat(description, scorm2004_regex.CMILangString250,
true)) {
this.#description = description;
}
}
@@ -1121,7 +1131,8 @@ export class CMIObjectivesObject extends BaseCMI {
* @param {string} description
*/
set description(description) {
if (check2004ValidFormat(description, scorm2004_regex.CMILangString250, true)) {
if (check2004ValidFormat(description, scorm2004_regex.CMILangString250,
true)) {
this.#description = description;
}
}
@@ -1257,7 +1268,8 @@ export class CMICommentsObject extends BaseCMI {
if (this.initialized && this.#readOnlyAfterInit) {
throwReadOnlyError();
} else {
if (check2004ValidFormat(comment, scorm2004_regex.CMILangString4000, true)) {
if (check2004ValidFormat(comment, scorm2004_regex.CMILangString4000,
true)) {
this.#comment = comment;
}
}