Not requiring fields to be previously set while loading existing data

This commit is contained in:
Jonathan Putney
2020-07-30 16:54:15 -04:00
parent dcad088b25
commit c341d3f70f
6 changed files with 199 additions and 188 deletions

96
dist/scorm-again.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -848,7 +848,6 @@ export default class BaseAPI {
* @param {string} CMIElement
*/
loadFromFlattenedJSON(json, CMIElement) {
console.clear();
if (!this.isNotInitialized()) {
console.error(
'loadFromFlattenedJSON can only be called before the call to lmsInitialize.');
@@ -866,39 +865,23 @@ export default class BaseAPI {
function testPattern(a, c, a_pattern) {
const a_match = a.match(a_pattern);
if (a_match !== null) {
let c_match = c.match(
new RegExp(a_match[1] + Number(a_match[2]) + '.(.*)'));
if (c_match !== null) {
const a_int = Number(a_match[2]);
if (a_match[3] === 'id') {
return -1;
} else if (a_match[3] === 'type' && c_match[1] !== 'id') {
return -1;
} else {
return 1;
}
} else if ((c_match = c.match(a_pattern)) !== null) {
let c_match;
if (a_match !== null && (c_match = c.match(a_pattern)) !== null) {
return Number(a_match[2]) - Number(c_match[2]);
} else {
return testPattern(c, a, a_pattern);
}
}
return null;
}
/**
* Function to sort the array, which we'll call until we're done.
*
* @param {string} a
* @param {string} b
* @param {string} c
* @param {string} d
* @return {number}
*/
function resultSort([a, b], [c, d]) {
const int_pattern = /^(cmi\.interactions\.)(\d+)\.(.*)$/;
const obj_pattern = /^(cmi\.objectives\.)(\d+)\.(.*)$/;
const result = Object.keys(json).map(function(key) {
return [String(key), json[key]];
});
// CMI interactions need to have id and type loaded before any other fields
result.sort(function([a, b], [c, d]) {
let test;
if ((test = testPattern(a, c, int_pattern)) !== null) {
return test;
@@ -914,25 +897,10 @@ export default class BaseAPI {
return 1;
}
return 0;
}
const int_pattern = /^(cmi\.interactions\.)(\d+)\.(.*)$/;
const obj_pattern = /^(cmi\.objectives\.)(\d+)\.(.*)$/;
const result = Object.keys(json).map(function(key) {
return [String(key), json[key]];
});
// CMI interactions need to have id and type loaded before any other fields
// Call the sort until everything is properly sorted.
// I must be missing an edge case in my sort?
let sorted_result = [];
while (sorted_result !== result.sort(resultSort)) {
sorted_result = result;
}
let obj;
sorted_result.forEach((element) => {
result.forEach((element) => {
obj = {};
obj[element[0]] = element[1];
this.loadFromJSON(unflatten(obj), CMIElement);

View File

@@ -194,8 +194,10 @@ export default class Scorm2004API extends BaseAPI {
const parts = CMIElement.split('.');
const index = Number(parts[2]);
const interaction = this.cmi.interactions.childArray[index];
if (this.isInitialized()) {
if (!interaction.type) {
this.throwSCORMError(scorm2004_error_codes.DEPENDENCY_NOT_ESTABLISHED);
this.throwSCORMError(
scorm2004_error_codes.DEPENDENCY_NOT_ESTABLISHED);
} else {
const interaction_type = interaction.type;
const interaction_count = interaction.correct_responses._count;
@@ -229,6 +231,7 @@ export default class Scorm2004API extends BaseAPI {
'Incorrect Response Type: ' + interaction_type);
}
}
}
if (this.lastErrorCode === 0) {
newChild = new CMIInteractionsCorrectResponsesObject();
}

View File

@@ -819,7 +819,7 @@ export class CMIInteractionsObject extends BaseCMI {
* @param {string} type
*/
set type(type) {
if (typeof this.id === 'undefined') {
if (this.initialized && typeof this.id === 'undefined') {
throw new ValidationError(
scorm2004_error_codes.DEPENDENCY_NOT_ESTABLISHED);
} else {
@@ -842,10 +842,15 @@ export class CMIInteractionsObject extends BaseCMI {
* @param {string} timestamp
*/
set timestamp(timestamp) {
if (this.initialized && typeof this.id === 'undefined') {
throw new ValidationError(
scorm2004_error_codes.DEPENDENCY_NOT_ESTABLISHED);
} else {
if (check2004ValidFormat(timestamp, scorm2004_regex.CMITime)) {
this.#timestamp = timestamp;
}
}
}
/**
* Getter for #weighting
@@ -860,10 +865,15 @@ export class CMIInteractionsObject extends BaseCMI {
* @param {string} weighting
*/
set weighting(weighting) {
if (this.initialized && typeof this.id === 'undefined') {
throw new ValidationError(
scorm2004_error_codes.DEPENDENCY_NOT_ESTABLISHED);
} else {
if (check2004ValidFormat(weighting, scorm2004_regex.CMIDecimal)) {
this.#weighting = weighting;
}
}
}
/**
* Getter for #learner_response
@@ -879,7 +889,8 @@ export class CMIInteractionsObject extends BaseCMI {
* @param {string} learner_response
*/
set learner_response(learner_response) {
if (typeof this.type === 'undefined' || typeof this.id === 'undefined') {
if (this.initialized && (typeof this.type === 'undefined' ||
typeof this.id === 'undefined')) {
throw new ValidationError(
scorm2004_error_codes.DEPENDENCY_NOT_ESTABLISHED);
} else {
@@ -962,10 +973,15 @@ export class CMIInteractionsObject extends BaseCMI {
* @param {string} latency
*/
set latency(latency) {
if (this.initialized && typeof this.id === 'undefined') {
throw new ValidationError(
scorm2004_error_codes.DEPENDENCY_NOT_ESTABLISHED);
} else {
if (check2004ValidFormat(latency, scorm2004_regex.CMITimespan)) {
this.#latency = latency;
}
}
}
/**
* Getter for #description
@@ -980,11 +996,16 @@ export class CMIInteractionsObject extends BaseCMI {
* @param {string} description
*/
set description(description) {
if (this.initialized && typeof this.id === 'undefined') {
throw new ValidationError(
scorm2004_error_codes.DEPENDENCY_NOT_ESTABLISHED);
} else {
if (check2004ValidFormat(description, scorm2004_regex.CMILangString250,
true)) {
this.#description = description;
}
}
}
/**
* toJSON for cmi.interactions.n
@@ -1081,10 +1102,15 @@ export class CMIObjectivesObject extends BaseCMI {
* @param {string} success_status
*/
set success_status(success_status) {
if (this.initialized && typeof this.id === 'undefined') {
throw new ValidationError(
scorm2004_error_codes.DEPENDENCY_NOT_ESTABLISHED);
} else {
if (check2004ValidFormat(success_status, scorm2004_regex.CMISStatus)) {
this.#success_status = success_status;
}
}
}
/**
* Getter for #completion_status
@@ -1099,10 +1125,15 @@ export class CMIObjectivesObject extends BaseCMI {
* @param {string} completion_status
*/
set completion_status(completion_status) {
if (this.initialized && typeof this.id === 'undefined') {
throw new ValidationError(
scorm2004_error_codes.DEPENDENCY_NOT_ESTABLISHED);
} else {
if (check2004ValidFormat(completion_status, scorm2004_regex.CMICStatus)) {
this.#completion_status = completion_status;
}
}
}
/**
* Getter for #progress_measure
@@ -1117,11 +1148,17 @@ export class CMIObjectivesObject extends BaseCMI {
* @param {string} progress_measure
*/
set progress_measure(progress_measure) {
if (this.initialized && typeof this.id === 'undefined') {
throw new ValidationError(
scorm2004_error_codes.DEPENDENCY_NOT_ESTABLISHED);
} else {
if (check2004ValidFormat(progress_measure, scorm2004_regex.CMIDecimal) &&
check2004ValidRange(progress_measure, scorm2004_regex.progress_range)) {
check2004ValidRange(progress_measure,
scorm2004_regex.progress_range)) {
this.#progress_measure = progress_measure;
}
}
}
/**
* Getter for #description
@@ -1136,11 +1173,16 @@ export class CMIObjectivesObject extends BaseCMI {
* @param {string} description
*/
set description(description) {
if (this.initialized && typeof this.id === 'undefined') {
throw new ValidationError(
scorm2004_error_codes.DEPENDENCY_NOT_ESTABLISHED);
} else {
if (check2004ValidFormat(description, scorm2004_regex.CMILangString250,
true)) {
this.#description = description;
}
}
}
/**
* toJSON for cmi.objectives.n