diff --git a/src/AICC.js b/src/AICC.js index c9bb9c8..ca693c7 100644 --- a/src/AICC.js +++ b/src/AICC.js @@ -4,8 +4,8 @@ import { CMI, CMIEvaluationCommentsObject, CMITriesObject, - NAV, } from './cmi/aicc_cmi'; +import {NAV} from './cmi/scorm12_cmi'; /** * The AICC API class diff --git a/src/BaseAPI.js b/src/BaseAPI.js index 9e0282f..49dcbe1 100644 --- a/src/BaseAPI.js +++ b/src/BaseAPI.js @@ -17,6 +17,7 @@ export default class BaseAPI { autocommitSeconds: 60, lmsCommitUrl: false, dataCommitFormat: 'json', // valid formats are 'json' or 'flattened', 'params' + auto_progress: false, }; cmi; startingData: {}; @@ -103,6 +104,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; diff --git a/src/Scorm12API.js b/src/Scorm12API.js index 36d6c36..ed2a518 100644 --- a/src/Scorm12API.js +++ b/src/Scorm12API.js @@ -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.auto_progress) { + this.processListeners('SequenceNext'); + } + } + + return result; } /** diff --git a/src/Scorm2004API.js b/src/Scorm2004API.js index e2b84ab..6b590fe 100644 --- a/src/Scorm2004API.js +++ b/src/Scorm2004API.js @@ -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.auto_progress) { + this.processListeners('SequenceNext'); + } + } + + return result; } /** diff --git a/src/cmi/aicc_cmi.js b/src/cmi/aicc_cmi.js index 0e5c5f9..22398b1 100644 --- a/src/cmi/aicc_cmi.js +++ b/src/cmi/aicc_cmi.js @@ -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; - } -} diff --git a/src/cmi/scorm12_cmi.js b/src/cmi/scorm12_cmi.js index c0e4730..b237170 100644 --- a/src/cmi/scorm12_cmi.js +++ b/src/cmi/scorm12_cmi.js @@ -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; + } +} diff --git a/test/cmi/aicc_cmi.spec.js b/test/cmi/aicc_cmi.spec.js index 6452515..fdb9175 100644 --- a/test/cmi/aicc_cmi.spec.js +++ b/test/cmi/aicc_cmi.spec.js @@ -4,12 +4,13 @@ import {scorm12_error_codes} from '../../src/constants/error_codes'; import { CMI, CMIEvaluationCommentsObject, - CMITriesObject, NAV, + CMITriesObject, } from '../../src/cmi/aicc_cmi'; import * as h from '../cmi_helpers'; import { CMIInteractionsObject, CMIObjectivesObject, + NAV, } from '../../src/cmi/scorm12_cmi'; import {expect} from 'chai'; import {scorm12_values} from '../../src/constants/field_values';