Merge branch 'master' of https://github.com/jcputney/scorm-again
This commit is contained in:
@@ -4,8 +4,8 @@ import {
|
||||
CMI,
|
||||
CMIEvaluationCommentsObject,
|
||||
CMITriesObject,
|
||||
NAV,
|
||||
} from './cmi/aicc_cmi';
|
||||
import {NAV} from './cmi/scorm12_cmi';
|
||||
|
||||
/**
|
||||
* The AICC API class
|
||||
|
||||
@@ -17,6 +17,9 @@ export default class BaseAPI {
|
||||
autocommitSeconds: 60,
|
||||
lmsCommitUrl: false,
|
||||
dataCommitFormat: 'json', // valid formats are 'json' or 'flattened', 'params'
|
||||
commitRequestDataType: 'application/json;charset=UTF-8',
|
||||
autoProgress: false,
|
||||
logLevel: global_constants.LOG_LEVEL_ERROR,
|
||||
};
|
||||
cmi;
|
||||
startingData: {};
|
||||
@@ -32,7 +35,6 @@ export default class BaseAPI {
|
||||
throw new TypeError('Cannot construct BaseAPI instances directly');
|
||||
}
|
||||
this.currentState = global_constants.STATE_NOT_INITIALIZED;
|
||||
this.apiLogLevel = global_constants.LOG_LEVEL_ERROR;
|
||||
this.lastErrorCode = 0;
|
||||
this.listenerArray = [];
|
||||
|
||||
@@ -40,6 +42,7 @@ export default class BaseAPI {
|
||||
this.#error_codes = error_codes;
|
||||
|
||||
this.settings = settings;
|
||||
this.apiLogLevel = this.settings.logLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -103,6 +106,13 @@ export default class BaseAPI {
|
||||
if (this.checkState(checkTerminated,
|
||||
this.#error_codes.TERMINATION_BEFORE_INIT,
|
||||
this.#error_codes.MULTIPLE_TERMINATION)) {
|
||||
const result = this.storeData(true);
|
||||
if (result.errorCode && result.errorCode > 0) {
|
||||
this.throwSCORMError(result.errorCode);
|
||||
}
|
||||
returnValue = result.result ?
|
||||
result.result : global_constants.SCORM_FALSE;
|
||||
|
||||
if (checkTerminated) this.lastErrorCode = 0;
|
||||
this.currentState = global_constants.STATE_TERMINATED;
|
||||
returnValue = global_constants.SCORM_TRUE;
|
||||
@@ -184,8 +194,8 @@ export default class BaseAPI {
|
||||
// If we didn't have any errors while setting the data, go ahead and
|
||||
// schedule a commit, if autocommit is turned on
|
||||
if (String(this.lastErrorCode) === '0') {
|
||||
if (this.#settings.autocommit && this.#timeout === undefined) {
|
||||
this.scheduleCommit(this.#settings.autocommitSeconds * 1000);
|
||||
if (this.settings.autocommit && !this.#timeout) {
|
||||
this.scheduleCommit(this.settings.autocommitSeconds * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -341,6 +351,13 @@ export default class BaseAPI {
|
||||
case global_constants.LOG_LEVEL_INFO:
|
||||
console.info(logMessage);
|
||||
break;
|
||||
case global_constants.LOG_LEVEL_DEBUG:
|
||||
if (console.debug) {
|
||||
console.debug(logMessage);
|
||||
} else {
|
||||
console.log(logMessage);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -611,7 +628,7 @@ export default class BaseAPI {
|
||||
}
|
||||
|
||||
refObject = refObject[attribute];
|
||||
if (!refObject) {
|
||||
if (refObject === undefined) {
|
||||
this.throwSCORMError(invalidErrorCode, invalidErrorMessage);
|
||||
break;
|
||||
}
|
||||
@@ -854,24 +871,32 @@ export default class BaseAPI {
|
||||
* @return {object}
|
||||
*/
|
||||
processHttpRequest(url: String, params) {
|
||||
const genericError = {
|
||||
'result': global_constants.SCORM_FALSE,
|
||||
'errorCode': this.#error_codes.GENERAL,
|
||||
};
|
||||
|
||||
const httpReq = new XMLHttpRequest();
|
||||
httpReq.open('POST', url, false);
|
||||
httpReq.setRequestHeader('Content-Type',
|
||||
'application/x-www-form-urlencoded');
|
||||
try {
|
||||
if (params instanceof Array) {
|
||||
httpReq.setRequestHeader('Content-Type',
|
||||
'application/x-www-form-urlencoded');
|
||||
httpReq.send(params.join('&'));
|
||||
} else {
|
||||
httpReq.send(params);
|
||||
httpReq.setRequestHeader('Content-Type',
|
||||
this.settings.commitRequestDataType);
|
||||
httpReq.send(JSON.stringify(params));
|
||||
}
|
||||
} catch (e) {
|
||||
return {
|
||||
'result': global_constants.SCORM_FALSE,
|
||||
'errorCode': this.#error_codes.GENERAL,
|
||||
};
|
||||
return genericError;
|
||||
}
|
||||
|
||||
return JSON.parse(httpReq.responseText);
|
||||
try {
|
||||
return JSON.parse(httpReq.responseText);
|
||||
} catch (e) {
|
||||
return genericError;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -881,6 +906,7 @@ export default class BaseAPI {
|
||||
*/
|
||||
scheduleCommit(when: number) {
|
||||
this.#timeout = new ScheduledCommit(this, when);
|
||||
this.apiLog('scheduleCommit', '', 'scheduled', global_constants.LOG_LEVEL_DEBUG);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -890,6 +916,8 @@ export default class BaseAPI {
|
||||
if (this.#timeout) {
|
||||
this.#timeout.cancel();
|
||||
this.#timeout = null;
|
||||
this.apiLog('clearScheduledCommit', '', 'cleared',
|
||||
global_constants.LOG_LEVEL_DEBUG);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -899,7 +927,7 @@ export default class BaseAPI {
|
||||
*/
|
||||
class ScheduledCommit {
|
||||
#API;
|
||||
#cancelled: false;
|
||||
#cancelled = false;
|
||||
#timeout;
|
||||
|
||||
/**
|
||||
@@ -909,7 +937,7 @@ class ScheduledCommit {
|
||||
*/
|
||||
constructor(API: any, when: number) {
|
||||
this.#API = API;
|
||||
this.#timeout = setTimeout(this.wrapper, when);
|
||||
this.#timeout = setTimeout(this.wrapper.bind(this), when);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,7 +5,7 @@ import {
|
||||
CMIInteractionsCorrectResponsesObject,
|
||||
CMIInteractionsObject,
|
||||
CMIInteractionsObjectivesObject,
|
||||
CMIObjectivesObject,
|
||||
CMIObjectivesObject, NAV,
|
||||
} from './cmi/scorm12_cmi';
|
||||
import * as Utilities from './utilities';
|
||||
import {global_constants, scorm12_constants} from './constants/api_constants';
|
||||
@@ -31,6 +31,8 @@ export default class Scorm12API extends BaseAPI {
|
||||
super(scorm12_error_codes, finalSettings);
|
||||
|
||||
this.cmi = new CMI();
|
||||
this.nav = new NAV();
|
||||
|
||||
// Rename functions to match 1.2 Spec and expose to modules
|
||||
this.LMSInitialize = this.lmsInitialize;
|
||||
this.LMSFinish = this.lmsFinish;
|
||||
@@ -59,7 +61,21 @@ export default class Scorm12API extends BaseAPI {
|
||||
* @return {string} bool
|
||||
*/
|
||||
lmsFinish() {
|
||||
return this.terminate('LMSFinish', false);
|
||||
const result = this.terminate('LMSFinish', false);
|
||||
|
||||
if (result === global_constants.SCORM_TRUE) {
|
||||
if (this.nav.event !== '') {
|
||||
if (this.nav.event === 'continue') {
|
||||
this.processListeners('SequenceNext');
|
||||
} else {
|
||||
this.processListeners('SequencePrevious');
|
||||
}
|
||||
} else if (this.settings.autoProgress) {
|
||||
this.processListeners('SequenceNext');
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -71,7 +71,39 @@ export default class Scorm2004API extends BaseAPI {
|
||||
* @return {string} bool
|
||||
*/
|
||||
lmsTerminate() {
|
||||
return this.terminate('Terminate', true);
|
||||
const result = this.terminate('Terminate', true);
|
||||
|
||||
if (result === global_constants.SCORM_TRUE) {
|
||||
if (this.adl.nav.request !== '_none_') {
|
||||
switch (this.adl.nav.request) {
|
||||
case 'continue':
|
||||
this.processListeners('SequenceNext');
|
||||
break;
|
||||
case 'previous':
|
||||
this.processListeners('SequencePrevious');
|
||||
break;
|
||||
case 'choice':
|
||||
this.processListeners('SequenceChoice');
|
||||
break;
|
||||
case 'exit':
|
||||
this.processListeners('SequenceExit');
|
||||
break;
|
||||
case 'exitAll':
|
||||
this.processListeners('SequenceExitAll');
|
||||
break;
|
||||
case 'abandon':
|
||||
this.processListeners('SequenceAbandon');
|
||||
break;
|
||||
case 'abandonAll':
|
||||
this.processListeners('SequenceAbandonAll');
|
||||
break;
|
||||
}
|
||||
} else if (this.settings.autoProgress) {
|
||||
this.processListeners('SequenceNext');
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -379,52 +379,3 @@ export class CMIEvaluationCommentsObject extends BaseCMI {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class for AICC Navigation object
|
||||
*/
|
||||
export class NAV extends BaseCMI {
|
||||
/**
|
||||
* Constructor for NAV object
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
#event = '';
|
||||
|
||||
/**
|
||||
* Getter for #event
|
||||
* @return {string}
|
||||
*/
|
||||
get event() {
|
||||
return (!this.jsonString) ? throwWriteOnlyError() : this.#event;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for #event
|
||||
* @param {string} event
|
||||
*/
|
||||
set event(event) {
|
||||
if (check12ValidFormat(event, regex.NAVEvent)) {
|
||||
this.#event = event;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* toJSON for nav object
|
||||
* @return {
|
||||
* {
|
||||
* event: string
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
toJSON() {
|
||||
this.jsonString = true;
|
||||
const result = {
|
||||
'event': this.event,
|
||||
};
|
||||
delete this.jsonString;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1205,3 +1205,52 @@ export class CMIInteractionsCorrectResponsesObject extends BaseCMI {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class for AICC Navigation object
|
||||
*/
|
||||
export class NAV extends BaseCMI {
|
||||
/**
|
||||
* Constructor for NAV object
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
#event = '';
|
||||
|
||||
/**
|
||||
* Getter for #event
|
||||
* @return {string}
|
||||
*/
|
||||
get event() {
|
||||
return (!this.jsonString) ? throwWriteOnlyError() : this.#event;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for #event
|
||||
* @param {string} event
|
||||
*/
|
||||
set event(event) {
|
||||
if (check12ValidFormat(event, regex.NAVEvent)) {
|
||||
this.#event = event;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* toJSON for nav object
|
||||
* @return {
|
||||
* {
|
||||
* event: string
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
toJSON() {
|
||||
this.jsonString = true;
|
||||
const result = {
|
||||
'event': this.event,
|
||||
};
|
||||
delete this.jsonString;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -428,7 +428,7 @@ export class CMI extends BaseCMI {
|
||||
* @param {string} suspend_data
|
||||
*/
|
||||
set suspend_data(suspend_data) {
|
||||
if (check2004ValidFormat(suspend_data, regex.CMIString64000)) {
|
||||
if (check2004ValidFormat(suspend_data, regex.CMIString64000, true)) {
|
||||
this.#suspend_data = suspend_data;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user