aboutsummaryrefslogtreecommitdiff
path: root/Info/9/3/Planet/tests/scorm-template/scorm-api.js
blob: a533757fe0f97dc68aad81a6712680e7ff66b744 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
let findAPITries = 0;
// Find SCORM 1.2 API algorithm taken from the SCORM documentation at:
// https://scorm.com/scorm-explained/technical-scorm/run-time/api-discovery-algorithms/
function findAPI(win) {
   // Check to see if the window (win) contains the API
   // if the window (win) does not contain the API and
   // the window (win) has a parent window and the parent window
   // is not the same as the window (win)
   while ( (win.API == null) && (win.parent != null) && (win.parent != win) )
   {
      // increment the number of findAPITries
      findAPITries++;
 
      // Note: 7 is an arbitrary number, but should be more than sufficient
      if (findAPITries > 7)
      {
         alert("Error finding API -- too deeply nested.");
         return null;
      }
 
      // set the variable that represents the window being
      // being searched to be the parent of the current window
      // then search for the API again
      win = win.parent;
   }
   return win.API;
}
 
function _getAPI() {
   // start by looking for the API in the current window
   var theAPI = findAPI(window);
 
   // if the API is null (could not be found in the current window)
   // and the current window has an opener window
   if ( (theAPI == null) && (window.opener != null) && (typeof(window.opener) != "undefined") )
   {
      // try to find the API in the current window’s opener
      theAPI = findAPI(window.opener);
   }
   // if the API has not been found
   if (theAPI == null)
   {
      // Alert the user that the API Adapter could not be found
      alert("Unable to find an API adapter");
   }
   return theAPI;
}


// SCORM 1.2 defines a bool as a string with the values "true" or "false"
function isScormTrue(b) {
	return b === "true";
}


class Scorm {
	api = null;
	// ensure LMSInitialize is only called once.
	initialized = false;
	// ensure LMSFinish is only called once.
	finished = false;

	getAPI() {
		if (this.api === null) {
			this.api = _getAPI();
		}
		return this.api;
	}

	initialize() {
		if (this.initialized) return true;
		const api = this.getAPI();
		if (!api) {
			console.warn("SCORM API not found");
			return false;
		}
		const r = api.LMSInitialize("");
		this.initialized = isScormTrue(r);
		return this.initialized;
	}

	finish() {
		if (this.finished) return true;
		const api = this.getAPI();
		if (!api) return false;
		const r = api.LMSFinish("");
		this.finished = isScormTrue(r);
		return this.finished;
	}

	getValue(el) {
		const api = this.getAPI();
		if (!api) return null;
		return api.LMSGetValue(el);
	}

	setValue(el, val) {
		const api = this.getAPI();
		if (!api) return false;
		const r = api.LMSSetValue(el, String(val));
		return isScormTrue(r);
	};

	commit() {
		const api = this.getAPI();
		if (!api) return false;
		const r = api.LMSCommit("");
		return isScormTrue(r);
	}

	setScore(raw, min, max) {
		this.setValue("cmi.core.score.raw", raw);
		if (min !== null) this.setValue("cmi.core.score.min", min);
		if (max !== null) this.setValue("cmi.core.score.max", max);
		this.commit();
	}
}

window.SCORM = new Scorm();

window.addEventListener("load", function() {
    window.SCORM.initialize();
});

// Finish on the before unloading the SCORM content as advised by the documentation:
// https://scorm.com/scorm-explained/technical-scorm/run-time/
window.addEventListener("beforeunload", function() {
    window.SCORM.commit();
    window.SCORM.finish();
});