scorm-again 1.6.1 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,50 +1,58 @@
1
1
  {
2
2
  "name": "scorm-again",
3
- "version": "1.6.1",
3
+ "version": "1.7.0",
4
4
  "description": "A modern SCORM JavaScript run-time library for AICC, SCORM 1.2, and SCORM 2004",
5
5
  "main": "dist/scorm-again.min.js",
6
+ "browserslist": [
7
+ "> 1%",
8
+ "edge >= 16",
9
+ "safari >= 9",
10
+ "firefox >= 57",
11
+ "ie >= 11",
12
+ "ios >= 9",
13
+ "chrome >= 49"
14
+ ],
6
15
  "directories": {
7
16
  "test": "test"
8
17
  },
9
18
  "devDependencies": {
10
- "@babel/cli": "^7.15.4",
11
- "@babel/core": "^7.15.5",
12
- "@babel/node": "^7.15.4",
13
- "@babel/plugin-proposal-class-properties": "^7.14.5",
14
- "@babel/plugin-proposal-optional-chaining": "^7.14.5",
15
- "@babel/plugin-proposal-private-methods": "^7.14.5",
16
- "@babel/preset-env": "^7.15.4",
17
- "@babel/preset-flow": "^7.14.5",
18
- "@babel/register": "^7.15.3",
19
- "@types/chai": "^4.2.21",
20
- "@types/mocha": "^9.0.0",
19
+ "@babel/cli": "^7.17.0",
20
+ "@babel/core": "^7.17.2",
21
+ "@babel/node": "^7.16.8",
22
+ "@babel/plugin-proposal-class-properties": "^7.16.7",
23
+ "@babel/plugin-proposal-optional-chaining": "^7.16.7",
24
+ "@babel/plugin-proposal-private-methods": "^7.16.11",
25
+ "@babel/preset-env": "^7.16.11",
26
+ "@babel/preset-flow": "^7.16.7",
27
+ "@babel/register": "^7.17.0",
28
+ "@types/chai": "^4.3.0",
29
+ "@types/mocha": "^9.1.0",
21
30
  "babel-eslint": "^11.0.0-beta.2",
31
+ "babel-loader": "^8.2.3",
22
32
  "babelify": "^10.0.0",
23
33
  "browserify": "^17.0.0",
24
- "chai": "^4.3.4",
25
- "eslint": "^7.32.0",
34
+ "chai": "^4.3.6",
35
+ "eslint": "^8.8.0",
26
36
  "eslint-config-google": "^0.14.0",
27
- "eslint-plugin-import": "^2.24.2",
37
+ "eslint-plugin-import": "^2.25.4",
38
+ "eslint-webpack-plugin": "^3.1.1",
28
39
  "fetch-pretender": "^1.5.0",
29
- "grunt": "^1.4.1",
30
- "grunt-browserify": "^6.0.0",
31
- "grunt-cli": "^1.4.3",
32
- "grunt-contrib-watch": "^1.1.0",
33
- "grunt-mocha-test": "^0.13.3",
34
- "jsdoc": "^3.6.7",
40
+ "jsdoc": "^3.6.10",
35
41
  "jsdoc-babel": "^0.5.0",
36
42
  "lodash.debounce": "^4.0.8",
37
43
  "minimist": "^1.2.5",
38
- "mocha": "^9.1.1",
39
- "mocha-junit-reporter": "^2.0.0",
40
- "mochawesome": "^6.2.1",
44
+ "mocha": "^9.2.0",
45
+ "mocha-junit-reporter": "^2.0.2",
46
+ "mochawesome": "^7.0.1",
41
47
  "nyc": "^15.1.0",
42
- "sinon": "^11.1.2",
43
- "uglifyify": "^5.0.2"
48
+ "sinon": "^13.0.1",
49
+ "uglifyjs-webpack-plugin": "^2.2.0",
50
+ "webpack": "^5.68.0",
51
+ "webpack-cli": "^4.9.2"
44
52
  },
45
53
  "scripts": {
46
54
  "test": "./node_modules/.bin/mocha --require @babel/register --bdd --recursive --reporter list",
47
- "compile": "./node_modules/.bin/grunt default",
55
+ "compile": "./node_modules/.bin/webpack --bail --config webpack.js",
48
56
  "fix": "./node_modules/.bin/eslint ./src --fix"
49
57
  },
50
58
  "repository": {
package/src/BaseAPI.js CHANGED
@@ -29,6 +29,8 @@ export default class BaseAPI {
29
29
  selfReportSessionTime: false,
30
30
  alwaysSendTotalTime: false,
31
31
  strict_errors: true,
32
+ xhrHeaders: {},
33
+ xhrWithCredentials: false,
32
34
  responseHandler: function(xhr) {
33
35
  let result;
34
36
  if (typeof xhr !== 'undefined') {
@@ -46,6 +48,29 @@ export default class BaseAPI {
46
48
  }
47
49
  return result;
48
50
  },
51
+ requestHandler: function(commitObject) {
52
+ return commitObject;
53
+ },
54
+ onLogMessage: function(messageLevel, logMessage) {
55
+ switch (messageLevel) {
56
+ case global_constants.LOG_LEVEL_ERROR:
57
+ console.error(logMessage);
58
+ break;
59
+ case global_constants.LOG_LEVEL_WARNING:
60
+ console.warn(logMessage);
61
+ break;
62
+ case global_constants.LOG_LEVEL_INFO:
63
+ console.info(logMessage);
64
+ break;
65
+ case global_constants.LOG_LEVEL_DEBUG:
66
+ if (console.debug) {
67
+ console.debug(logMessage);
68
+ } else {
69
+ console.log(logMessage);
70
+ }
71
+ break;
72
+ }
73
+ },
49
74
  };
50
75
  cmi;
51
76
  startingData: {};
@@ -149,11 +174,11 @@ export default class BaseAPI {
149
174
 
150
175
  const result = this.storeData(true);
151
176
  if (!this.settings.sendBeaconCommit && !this.settings.asyncCommit &&
152
- typeof result.errorCode !== 'undefined' && result.errorCode > 0) {
177
+ typeof result.errorCode !== 'undefined' && result.errorCode > 0) {
153
178
  this.throwSCORMError(result.errorCode);
154
179
  }
155
180
  returnValue = (typeof result !== 'undefined' && result.result) ?
156
- result.result : global_constants.SCORM_FALSE;
181
+ result.result : global_constants.SCORM_FALSE;
157
182
 
158
183
  if (checkTerminated) this.lastErrorCode = 0;
159
184
 
@@ -290,11 +315,11 @@ export default class BaseAPI {
290
315
  this.#error_codes.COMMIT_AFTER_TERM)) {
291
316
  const result = this.storeData(false);
292
317
  if (!this.settings.sendBeaconCommit && !this.settings.asyncCommit &&
293
- result.errorCode && result.errorCode > 0) {
318
+ result.errorCode && result.errorCode > 0) {
294
319
  this.throwSCORMError(result.errorCode);
295
320
  }
296
321
  returnValue = (typeof result !== 'undefined' && result.result) ?
297
- result.result : global_constants.SCORM_FALSE;
322
+ result.result : global_constants.SCORM_FALSE;
298
323
 
299
324
  this.apiLog(callbackName, 'HttpRequest', ' Result: ' + returnValue,
300
325
  global_constants.LOG_LEVEL_DEBUG);
@@ -408,24 +433,7 @@ export default class BaseAPI {
408
433
  logMessage = this.formatMessage(functionName, CMIElement, logMessage);
409
434
 
410
435
  if (messageLevel >= this.apiLogLevel) {
411
- switch (messageLevel) {
412
- case global_constants.LOG_LEVEL_ERROR:
413
- console.error(logMessage);
414
- break;
415
- case global_constants.LOG_LEVEL_WARNING:
416
- console.warn(logMessage);
417
- break;
418
- case global_constants.LOG_LEVEL_INFO:
419
- console.info(logMessage);
420
- break;
421
- case global_constants.LOG_LEVEL_DEBUG:
422
- if (console.debug) {
423
- console.debug(logMessage);
424
- } else {
425
- console.log(logMessage);
426
- }
427
- break;
428
- }
436
+ this.settings.onLogMessage(messageLevel, logMessage);
429
437
  }
430
438
  }
431
439
 
@@ -490,9 +498,9 @@ export default class BaseAPI {
490
498
  */
491
499
  _checkObjectHasProperty(refObject, attribute: String) {
492
500
  return Object.hasOwnProperty.call(refObject, attribute) ||
493
- Object.getOwnPropertyDescriptor(
494
- Object.getPrototypeOf(refObject), attribute) ||
495
- (attribute in refObject);
501
+ Object.getOwnPropertyDescriptor(
502
+ Object.getPrototypeOf(refObject), attribute) ||
503
+ (attribute in refObject);
496
504
  }
497
505
 
498
506
  /**
@@ -556,21 +564,21 @@ export default class BaseAPI {
556
564
 
557
565
  const invalidErrorMessage = `The data model element passed to ${methodName} (${CMIElement}) is not a valid SCORM data model element.`;
558
566
  const invalidErrorCode = scorm2004 ?
559
- this.#error_codes.UNDEFINED_DATA_MODEL :
560
- this.#error_codes.GENERAL;
567
+ this.#error_codes.UNDEFINED_DATA_MODEL :
568
+ this.#error_codes.GENERAL;
561
569
 
562
570
  for (let i = 0; i < structure.length; i++) {
563
571
  const attribute = structure[i];
564
572
 
565
573
  if (i === structure.length - 1) {
566
574
  if (scorm2004 && (attribute.substr(0, 8) === '{target=') &&
567
- (typeof refObject._isTargetValid == 'function')) {
575
+ (typeof refObject._isTargetValid == 'function')) {
568
576
  this.throwSCORMError(this.#error_codes.READ_ONLY_ELEMENT);
569
577
  } else if (!this._checkObjectHasProperty(refObject, attribute)) {
570
578
  this.throwSCORMError(invalidErrorCode, invalidErrorMessage);
571
579
  } else {
572
580
  if (this.isInitialized() &&
573
- this.stringMatches(CMIElement, '\\.correct_responses\\.\\d+')) {
581
+ this.stringMatches(CMIElement, '\\.correct_responses\\.\\d+')) {
574
582
  this.validateCorrectResponse(CMIElement, value);
575
583
  }
576
584
 
@@ -671,8 +679,8 @@ export default class BaseAPI {
671
679
  const uninitializedErrorMessage = `The data model element passed to ${methodName} (${CMIElement}) has not been initialized.`;
672
680
  const invalidErrorMessage = `The data model element passed to ${methodName} (${CMIElement}) is not a valid SCORM data model element.`;
673
681
  const invalidErrorCode = scorm2004 ?
674
- this.#error_codes.UNDEFINED_DATA_MODEL :
675
- this.#error_codes.GENERAL;
682
+ this.#error_codes.UNDEFINED_DATA_MODEL :
683
+ this.#error_codes.GENERAL;
676
684
 
677
685
  for (let i = 0; i < structure.length; i++) {
678
686
  attribute = structure[i];
@@ -686,9 +694,8 @@ export default class BaseAPI {
686
694
  }
687
695
  } else {
688
696
  if ((String(attribute).substr(0, 8) === '{target=') &&
689
- (typeof refObject._isTargetValid == 'function')) {
690
- const target = String(attribute).
691
- substr(8, String(attribute).length - 9);
697
+ (typeof refObject._isTargetValid == 'function')) {
698
+ const target = String(attribute).substr(8, String(attribute).length - 9);
692
699
  return refObject._isTargetValid(target);
693
700
  } else if (!this._checkObjectHasProperty(refObject, attribute)) {
694
701
  this.throwSCORMError(invalidErrorCode, invalidErrorMessage);
@@ -818,7 +825,7 @@ export default class BaseAPI {
818
825
  const removeIndex = this.listenerArray.findIndex((obj) =>
819
826
  obj.functionName === functionName &&
820
827
  obj.CMIElement === CMIElement &&
821
- obj.callback === callback
828
+ obj.callback === callback,
822
829
  );
823
830
  if (removeIndex !== -1) {
824
831
  this.listenerArray.splice(removeIndex, 1);
@@ -867,8 +874,8 @@ export default class BaseAPI {
867
874
  const listenerHasCMIElement = !!listener.CMIElement;
868
875
  let CMIElementsMatch = false;
869
876
  if (CMIElement && listener.CMIElement &&
870
- listener.CMIElement.substring(listener.CMIElement.length - 1) ===
871
- '*') {
877
+ listener.CMIElement.substring(listener.CMIElement.length - 1) ===
878
+ '*') {
872
879
  CMIElementsMatch = CMIElement.indexOf(listener.CMIElement.substring(0,
873
880
  listener.CMIElement.length - 1)) === 0;
874
881
  } else {
@@ -1093,6 +1100,15 @@ export default class BaseAPI {
1093
1100
  if (!settings.sendBeaconCommit) {
1094
1101
  const httpReq = new XMLHttpRequest();
1095
1102
  httpReq.open('POST', url, settings.asyncCommit);
1103
+
1104
+ if (Object.keys(settings.xhrHeaders).length) {
1105
+ Object.keys(settings.xhrHeaders).forEach((header) => {
1106
+ httpReq.setRequestHeader(header, settings.xhrHeaders[header]);
1107
+ });
1108
+ }
1109
+
1110
+ httpReq.withCredentials = settings.xhrWithCredentials;
1111
+
1096
1112
  if (settings.asyncCommit) {
1097
1113
  httpReq.onload = function(e) {
1098
1114
  if (typeof settings.responseHandler === 'function') {
@@ -1103,6 +1119,7 @@ export default class BaseAPI {
1103
1119
  };
1104
1120
  }
1105
1121
  try {
1122
+ params = settings.requestHandler(params);
1106
1123
  if (params instanceof Array) {
1107
1124
  httpReq.setRequestHeader('Content-Type',
1108
1125
  'application/x-www-form-urlencoded');
@@ -1164,7 +1181,7 @@ export default class BaseAPI {
1164
1181
  }
1165
1182
 
1166
1183
  if (result.result === true ||
1167
- result.result === global_constants.SCORM_TRUE) {
1184
+ result.result === global_constants.SCORM_TRUE) {
1168
1185
  api.processListeners('CommitSuccess');
1169
1186
  } else {
1170
1187
  api.processListeners('CommitError');
package/webpack.js ADDED
@@ -0,0 +1,78 @@
1
+ const path = require('path');
2
+ const webpack = require('webpack');
3
+ const ESLintPlugin = require('eslint-webpack-plugin');
4
+ const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
5
+
6
+ const JSLoader = {
7
+ test: /\.js$/i,
8
+ use: {
9
+ loader: 'babel-loader',
10
+ options: {
11
+ presets: [
12
+ [
13
+ '@babel/preset-env',
14
+ {
15
+ 'corejs': '3',
16
+ 'useBuiltIns': 'entry',
17
+ 'targets': {
18
+ 'browsers': [
19
+ 'edge >= 16',
20
+ 'safari >= 9',
21
+ 'firefox >= 57',
22
+ 'ie >= 11',
23
+ 'ios >= 9',
24
+ 'chrome >= 49',
25
+ ],
26
+ },
27
+ },
28
+ ],
29
+ ['@babel/preset-flow'],
30
+ ],
31
+ plugins: [
32
+ '@babel/plugin-proposal-class-properties',
33
+ '@babel/plugin-proposal-private-methods',
34
+ '@babel/plugin-proposal-optional-chaining',
35
+ ],
36
+ },
37
+ },
38
+ };
39
+
40
+ module.exports = {
41
+ mode: 'development',
42
+ devtool: 'source-map',
43
+ entry: {
44
+ 'aicc': './src/exports/aicc.js',
45
+ 'scorm12': './src/exports/scorm12.js',
46
+ 'scorm2004': './src/exports/scorm2004.js',
47
+ 'scorm-again': './src/exports/scorm-again.js',
48
+ 'aicc.min': './src/exports/aicc.js',
49
+ 'scorm12.min': './src/exports/scorm12.js',
50
+ 'scorm2004.min': './src/exports/scorm2004.js',
51
+ 'scorm-again.min': './src/exports/scorm-again.js',
52
+ },
53
+ target: ['web', 'es5'],
54
+ module: {
55
+ rules: [
56
+ JSLoader,
57
+ ],
58
+ },
59
+ output: {
60
+ path: path.resolve(__dirname, 'dist'),
61
+ environment: {
62
+ arrowFunction: false,
63
+ },
64
+ },
65
+ optimization: {
66
+ minimize: true,
67
+ minimizer: [new UglifyJsPlugin({
68
+ include: /\.min\.js$/,
69
+ })],
70
+ },
71
+ plugins: [
72
+ new ESLintPlugin({
73
+ overrideConfigFile: path.resolve(__dirname, '.eslintrc.js'),
74
+ context: path.resolve(__dirname, '../src'),
75
+ files: '**/*.js',
76
+ }),
77
+ ],
78
+ };
package/gruntfile.js DELETED
@@ -1,90 +0,0 @@
1
- module.exports = function(grunt) {
2
- grunt.initConfig({
3
- mochaTest: {
4
- test: {
5
- options: {
6
- reporter: 'list',
7
- require: '@babel/register',
8
- noFail: false,
9
- recursive: true,
10
- captureFile: false,
11
- },
12
- src: ['test/**/*.spec.js'],
13
- },
14
- },
15
- watch: {
16
- scripts: {
17
- files: ['src/**/*.js'],
18
- tasks: ['default'],
19
- options: {
20
- spawn: false,
21
- },
22
- },
23
- },
24
- browserify: {
25
- development: {
26
- files: [{
27
- expand: true,
28
- cwd: 'src/exports/',
29
- src: ['*.js'],
30
- dest: 'dist/',
31
- ext: '.js',
32
- extDot: 'first',
33
- }],
34
- options: {
35
- browserifyOptions: {debug: true},
36
- transform: [
37
- [
38
- 'babelify', {
39
- 'presets': ['@babel/preset-env', '@babel/preset-flow'],
40
- 'plugins': [
41
- '@babel/plugin-proposal-class-properties',
42
- '@babel/plugin-proposal-private-methods',
43
- '@babel/plugin-proposal-optional-chaining',
44
- ],
45
- },
46
- ],
47
- ],
48
- },
49
- },
50
- production: {
51
- files: [{
52
- expand: true,
53
- cwd: 'src/exports/',
54
- src: ['*.js'],
55
- dest: 'dist/',
56
- ext: '.min.js',
57
- extDot: 'first',
58
- }],
59
- options: {
60
- browserifyOptions: {debug: false},
61
- transform: [
62
- [
63
- 'babelify', {
64
- 'presets': ['@babel/preset-env', '@babel/preset-flow'],
65
- 'plugins': [
66
- '@babel/plugin-proposal-class-properties',
67
- '@babel/plugin-proposal-private-methods',
68
- '@babel/plugin-proposal-optional-chaining',
69
- ],
70
- },
71
- 'uglifyify', {
72
- sourceMap: true,
73
- },
74
- ],
75
- ],
76
- },
77
- },
78
- },
79
-
80
- });
81
-
82
- grunt.loadNpmTasks('grunt-browserify');
83
- grunt.loadNpmTasks('grunt-mocha-test');
84
- grunt.loadNpmTasks('grunt-contrib-watch');
85
-
86
- grunt.registerTask('test', 'mochaTest');
87
-
88
- grunt.registerTask('default',
89
- ['browserify:development', 'browserify:production']);
90
- };