qti3-item-player-vue3 0.2.12 → 0.2.14

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.
@@ -13,107 +13,130 @@
13
13
  ></script>
14
14
  <script>
15
15
  let qtiCustomInteractionContext = {
16
- // A field holding the interactions registered during initialization.
17
- customInteractions: {},
18
- interactions:[],
19
-
20
- /**
21
- * - Communication Bridge API: getInstance
22
- *
23
- * This method can be called by rendering engines to create a new
24
- * instance of a PCI of the specified type.
25
- * For composite items this method could be called multiple times
26
- * on the same web page for the same typeIdentifier.
27
- * @param {string} typeIdentifier the interaction type to create. Must be
28
- * the same value as the custom-interaction-type-identifier attribute of the
29
- * qti-portable-interaction
30
- * @param {HTMLElement} dom The DOM element where the markup from the
31
- * qti-portable-interaction element has been rendered.
32
- * @param {Object.<string, Object>} configuration
33
- * @param {string} state A representation of the state of the interaction which
34
- * the customInteraction will later accept in a
35
- * getInstance call to recreate an equivalent interaction state.
36
- */
37
- getInstance: function(typeIdentifier, dom, configuration, state) {
38
- console.log('[PCI Context] Interaction GetInstance: ' + typeIdentifier);
39
- const customInteraction = this.customInteractions[typeIdentifier];
16
+ // A field holding the interactions registered during initialization.
17
+ // However, because this renderer is iframed, there is never going to be
18
+ // more than one PCI initialized.
19
+ customInteractions: {},
20
+ interactions:[],
21
+
22
+ /**
23
+ * - Communication Bridge API: getInstance
24
+ *
25
+ * This method can be called by rendering engines to create a new
26
+ * instance of a PCI of the specified type.
27
+ * For composite items this method could be called multiple times
28
+ * on the same web page for the same typeIdentifier.
29
+ * @param {string} typeIdentifier the interaction type to create. Must be
30
+ * the same value as the custom-interaction-type-identifier attribute of the
31
+ * qti-portable-interaction
32
+ * @param {HTMLElement} dom The DOM element where the markup from the
33
+ * qti-portable-interaction element has been rendered.
34
+ * @param {Object.<string, Object>} configuration
35
+ * @param {string} state A representation of the state of the interaction which
36
+ * the customInteraction will later accept in a
37
+ * getInstance call to recreate an equivalent interaction state.
38
+ */
39
+ getInstance: function(typeIdentifier, dom, configuration, state) {
40
+ console.log('[PCI Context] Interaction GetInstance: ' + typeIdentifier);
41
+ const customInteraction = this.customInteractions[typeIdentifier];
40
42
  //
41
- // It is more reliable to get the instance in the onready callback.
42
- // See notifyReady.
43
+ // It is more reliable to get the instance in the notifyReady callback.
44
+ // See the notifyReady callback method to get a handle on the instance.
43
45
  //
44
- let instance = customInteraction.getInstance(dom, configuration, state);
45
- //return instance;
46
- },
47
-
48
- /**
49
- * - Communication Bridge API: register
50
- *
51
- * This method is called by Custom Interaction Hooks to register
52
- * with the Rendering Engine for later cloning via a call to getInstance.
53
- * This method is called by Custom Interaction Hooks during the loading of
54
- * the JavaScript implementation.
55
- *
56
- * @param {Object} customInteraction A Custom Interaction object.
57
- */
58
- register: function(customInteraction) {
59
- console.log('[PCI Context] Interaction Registered: ' + customInteraction.typeIdentifier);
60
- this.customInteractions[customInteraction.typeIdentifier] = customInteraction;
61
- },
62
-
63
- /**
64
- * - Communication Bridge API: notifyReady
65
- *
66
- * This method must be called by a Custom Interaction Instance
67
- * to inform it is ready to be used.
68
- *
69
- * @callback notifyReady
70
- * @param {Object} customInteraction The Custom Interaction Instance.
71
- * @param {string} state A representation of the state of the interaction which
72
- * the customInteraction will later accept in a
73
- * getInstance call to recreate an equivalent interaction state.
74
- */
75
- notifyReady: function(customInteraction, state) {
76
- console.log('[PCI Context] Interaction Ready: ' + customInteraction.typeIdentifier);
46
+ customInteraction.getInstance(dom, configuration, state)
47
+ },
48
+
49
+ /**
50
+ * - Communication Bridge API: register
51
+ *
52
+ * This method is called by Custom Interaction Hooks to register
53
+ * with the Rendering Engine for later cloning via a call to getInstance.
54
+ * This method is called by Custom Interaction Hooks during the loading of
55
+ * the JavaScript implementation.
56
+ *
57
+ * @param {Object} customInteraction A Custom Interaction object.
58
+ */
59
+ register (customInteraction) {
60
+ console.log('[PCI Context] Interaction Registered: ' + customInteraction.typeIdentifier)
61
+ this.customInteractions[customInteraction.typeIdentifier] = customInteraction
62
+ },
63
+
64
+ /**
65
+ * - Communication Bridge API: notifyReady
66
+ *
67
+ * This method MUST be called by a Custom Interaction Instance
68
+ * to inform the delivery engine it is ready to be used.
69
+ *
70
+ * @callback notifyReady
71
+ * @param {Object} instance The Custom Interaction Instance.
72
+ * @param {string} state A representation of the state of the interaction which
73
+ * the customInteraction will later accept in a
74
+ * getInstance call to recreate an equivalent interaction state.
75
+ */
76
+ notifyReady (instance, state) {
77
+ console.log('[PCI Context] Interaction Ready: ' + instance.typeIdentifier)
77
78
  // IMPORTANT: Pass the instance back to the QTI_PCI_API
78
- QTI_PCI_API.NotifyPciReady(customInteraction);
79
- },
80
-
81
- /**
82
- * - Communication Bridge API: notifyDone
83
- *
84
- * The notifyDone method is optionally called by a Custom Interaction
85
- * instance to notify its end. The method exists in the event a
86
- * custom interaction has a determinate end.
87
- *
88
- * @callback notifyDone
89
- * @param {Object} customInteraction The Custom Interaction Instance.
90
- * @param {Object} response The final response value of the Custom Interaction Instance.
91
- * @param {Object} state The final state of the Custom Interaction Instance.
92
- * @param {Object} status The status of the Custom Interaction Instance.
93
- */
94
- notifyDone: function(customInteraction, response, state, status) {
95
- console.log('[PCI Context] Interaction Done: ' + customInteraction.typeIdentifier);
96
- QTI_PCI_API.NotifyPciDone(customInteraction, response, state, status);
97
- },
98
-
99
- /**
100
- * Allow the delivery engine to notify the PCI instance that it is being
101
- * destroyed via the Communication Bridge.
102
- * If the PCI is interested in being notified it will provide a function
103
- * to implement oncompleted.
104
- */
105
- oncompleted: function (instance) {
106
- // Fire oncompleted if available
107
- if ((typeof instance.oncompleted !== 'undefined') && (typeof instance.oncompleted == 'function')) {
108
- console.log('[PCI Context] Firing Interaction oncompleted: ' + instance.typeIdentifier);
109
- instance.oncompleted();
110
- }
111
- }
112
- };
113
-
79
+ QTI_PCI_API.NotifyPciReady(instance)
80
+ },
81
+
82
+ /**
83
+ * - Communication Bridge API: notifyDone
84
+ *
85
+ * The notifyDone method is optionally called by a Custom Interaction
86
+ * instance to notify its end. The method exists in the event a
87
+ * custom interaction has a determinate end; e.g., to simulate
88
+ * what happens in a QtiEndAttemptInteraction.
89
+ *
90
+ * @callback notifyDone
91
+ * @param {Object} instance The Custom Interaction Instance.
92
+ * @param {Object} response The final response value of the Custom Interaction Instance.
93
+ * @param {Object} state The final state of the Custom Interaction Instance.
94
+ * @param {String} status The status of the Custom Interaction Instance.
95
+ */
96
+ notifyDone (instance, response, state, status) {
97
+ console.log('[PCI Context] Interaction Done: ' + instance.typeIdentifier)
98
+ QTI_PCI_API.NotifyPciDone(instance, response, state, status)
99
+ },
100
+
101
+ /**
102
+ * Allow the delivery engine to notify the PCI instance that it is being
103
+ * destroyed via the Communication Bridge.
104
+ * If the PCI is interested in being notified it will provide a function
105
+ * to implement oncompleted.
106
+ */
107
+ oncompleted (instance) {
108
+ // Fire oncompleted if available
109
+ if ((typeof instance.oncompleted !== 'undefined') && (typeof instance.oncompleted == 'function')) {
110
+ console.log('[PCI Context] Firing Interaction oncompleted: ' + instance.typeIdentifier)
111
+ instance.oncompleted()
112
+ }
113
+ },
114
+
115
+ /**
116
+ * Allow the delivery engine to notify the PCI instance that there has been a
117
+ * change to the rendering properties AFTER the PCI instance has been created via
118
+ * getInstance.
119
+ * If the PCI is interested in being notified it will provide a function
120
+ * to implement setRenderingProperties.
121
+
122
+ * @param {Object} instance The Custom Interaction Instance.
123
+ * @param {Object} properties Properties is an Object consisting of two properties:
124
+ * {
125
+ * pnp: { "access-for-all-pnp": { <afapnp> } },
126
+ * status: "<item lifecycle status>" // 'initial' | 'interacting' | 'closed' | 'review' | 'solution'
127
+ * }
128
+ */
129
+ setRenderingProperties (instance, properties) {
130
+ if ((typeof instance.setRenderingProperties !== 'undefined') && typeof instance.setRenderingProperties == 'function') {
131
+ console.log('[PCI Context] Interaction SetRenderingProperties:', properties)
132
+ instance.setRenderingProperties(properties)
133
+ }
134
+ }
135
+ }
136
+
114
137
  define('qtiCustomInteractionContext',[],function(){
115
138
  return qtiCustomInteractionContext;
116
- });
139
+ })
117
140
 
118
141
  /**
119
142
  * Provides an interface between the parent window and this child page
@@ -129,6 +152,7 @@ const QTI_PCI_API = {
129
152
  templateVariables: null,
130
153
  stylesheets: null,
131
154
  catalogInfo: null,
155
+ pnp: null,
132
156
  moduleResolution: null,
133
157
  instance: null,
134
158
  response: null,
@@ -140,125 +164,133 @@ const QTI_PCI_API = {
140
164
  onQtiInteractionChanged: null,
141
165
 
142
166
  getInstance () {
143
- return this.instance;
167
+ return this.instance
144
168
  },
145
169
 
146
170
  setInstance (instance) {
147
- this.instance = instance;
171
+ this.instance = instance
148
172
  },
149
173
 
150
174
  getTypeIdentifier () {
151
- return this.typeIdentifier;
175
+ return this.typeIdentifier
152
176
  },
153
177
 
154
178
  setTypeIdentifier (typeIdentifier) {
155
- this.typeIdentifier = typeIdentifier;
179
+ this.typeIdentifier = typeIdentifier
156
180
  },
157
181
 
158
182
  getResponseIdentifier () {
159
- return this.responseIdentifier;
183
+ return this.responseIdentifier
160
184
  },
161
185
 
162
186
  setResponseIdentifier (responseIdentifier) {
163
- this.responseIdentifier = responseIdentifier;
187
+ this.responseIdentifier = responseIdentifier
164
188
  },
165
189
 
166
190
  getPci () {
167
- return this.pci;
191
+ return this.pci
168
192
  },
169
193
 
170
194
  setPci (pci) {
171
- this.pci = pci;
195
+ this.pci = pci
172
196
  },
173
197
 
174
198
  getDom () {
175
- return this.dom;
199
+ return this.dom
176
200
  },
177
201
 
178
202
  setDom (dom) {
179
- this.dom = dom;
203
+ this.dom = dom
180
204
  },
181
205
 
182
206
  getProperties () {
183
- return this.properties;
207
+ return this.properties
184
208
  },
185
209
 
186
210
  setProperties (properties) {
187
- this.properties = properties;
211
+ this.properties = properties
188
212
  },
189
213
 
190
214
  getContextVariables () {
191
- return this.contextVariables;
215
+ return this.contextVariables
192
216
  },
193
217
 
194
218
  setContextVariables (contextVariables) {
195
- this.contextVariables = contextVariables;
219
+ this.contextVariables = contextVariables
196
220
  },
197
221
 
198
222
  getTemplateVariables () {
199
- return this.templateVariables;
223
+ return this.templateVariables
200
224
  },
201
225
 
202
226
  setTemplateVariables (templateVariables) {
203
- this.templateVariables = templateVariables;
227
+ this.templateVariables = templateVariables
204
228
  },
205
229
 
206
230
  getStylesheets () {
207
- return this.stylesheets;
231
+ return this.stylesheets
208
232
  },
209
233
 
210
234
  setStylesheets (stylesheets) {
211
235
  if (typeof stylesheets === 'undefined') return;
212
- this.stylesheets = stylesheets;
236
+ this.stylesheets = stylesheets
213
237
  },
214
238
 
215
239
  getCatalogInfo () {
216
- return this.catalogInfo;
240
+ return this.catalogInfo
217
241
  },
218
242
 
219
243
  setCatalogInfo (catalogInfo) {
220
- if (typeof catalogInfo === 'undefined') return;
221
- this.catalogInfo = catalogInfo;
244
+ if (typeof catalogInfo === 'undefined') return
245
+ this.catalogInfo = catalogInfo
246
+ },
247
+
248
+ getPnp () {
249
+ return this.pnp
250
+ },
251
+
252
+ setPnp (pnp) {
253
+ this.pnp = pnp
222
254
  },
223
255
 
224
256
  getBoundTo () {
225
- return this.boundTo;
257
+ return this.boundTo[this.getResponseIdentifier()]
226
258
  },
227
259
 
228
260
  setBoundTo (boundTo) {
229
- this.boundTo = boundTo;
261
+ this.boundTo = boundTo
230
262
  },
231
263
 
232
264
  getStatus () {
233
- return this.status;
265
+ return this.status
234
266
  },
235
267
 
236
268
  setStatus (status) {
237
- this.status = status;
269
+ this.status = status
238
270
  },
239
271
 
240
272
  getModuleResolution () {
241
- return this.moduleResolution;
273
+ return this.moduleResolution
242
274
  },
243
275
 
244
276
  setModuleResolution (moduleResolution) {
245
- this.moduleResolution = moduleResolution;
277
+ this.moduleResolution = moduleResolution
246
278
  },
247
279
 
248
280
  getState () {
249
- return this.state;
281
+ return this.state
250
282
  },
251
283
 
252
284
  setState (state) {
253
- this.state = (typeof state === 'undefined') ? null : JSON.parse(state);
285
+ this.state = (typeof state === 'undefined') ? null : JSON.parse(state)
254
286
  },
255
287
 
256
288
  getStateFromState () {
257
- return (this.state === null) ? null : this.state.state;
289
+ return (this.state === null) ? null : this.state.state
258
290
  },
259
291
 
260
292
  getResponseFromState () {
261
- return (this.state === null) ? undefined : this.state.response;
293
+ return (this.state === null) ? undefined : this.state.response
262
294
  },
263
295
 
264
296
  /**
@@ -272,37 +304,38 @@ const QTI_PCI_API = {
272
304
  state: null
273
305
  }
274
306
 
275
- const instance = this.getInstance();
307
+ const instance = this.getInstance()
276
308
 
277
309
  if (instance !== null) {
278
- let state = instance.getState();
279
- let response = instance.getResponse();
310
+ let state = instance.getState()
311
+ let response = instance.getResponse()
280
312
  // Convert undefined response to null
281
- obj.response = (typeof response === 'undefined') ? null : response;
282
- obj.state = state;
313
+ obj.response = (typeof response === 'undefined') ? null : response
314
+ obj.state = state
283
315
  }
284
316
 
285
- this.NotifyPciStateReady(JSON.stringify(obj));
317
+ this.NotifyPciStateReady(JSON.stringify(obj))
286
318
  },
287
319
 
288
320
  initialize (pci) {
289
- this.setDom(document.getElementById('qti3-player-pci-element'));
290
- this.setPci(pci);
291
- this.setTypeIdentifier(pci.typeIdentifier);
292
- this.setProperties(this.transformProperties(pci.properties));
293
- this.setModuleResolution(pci.moduleResolution);
294
- this.setContextVariables(pci.contextVariables);
295
- this.setTemplateVariables(pci.templateVariables);
296
- this.setStylesheets(pci.stylesheets);
297
- this.setCatalogInfo(pci.catalogInfo);
298
- this.setBoundTo(pci.boundTo);
321
+ this.setDom(document.getElementById('qti3-player-pci-element'))
322
+ this.setPci(pci)
323
+ this.setTypeIdentifier(pci.typeIdentifier)
324
+ this.setProperties(this.transformProperties(pci.properties))
325
+ this.setModuleResolution(pci.moduleResolution)
326
+ this.setContextVariables(pci.contextVariables)
327
+ this.setTemplateVariables(pci.templateVariables)
328
+ this.setStylesheets(pci.stylesheets)
329
+ this.setCatalogInfo(pci.catalogInfo)
330
+ this.setPnp(pci.pnp)
331
+ this.setBoundTo(pci.boundTo)
299
332
  this.setStatus(pci.status)
300
333
 
301
- this.trackResize(this.getDom());
302
- this.trackQtiInteractionChanged(this.getDom());
303
- this.injectStylesheets();
304
- this.injectClassAttribute();
305
- this.injectMarkup();
334
+ this.trackResize(this.getDom())
335
+ this.trackQtiInteractionChanged(this.getDom())
336
+ this.injectStylesheets()
337
+ this.injectClassAttribute()
338
+ this.injectMarkup()
306
339
  this.launchPci(
307
340
  this.getTypeIdentifier(),
308
341
  this.getDom(),
@@ -310,16 +343,17 @@ const QTI_PCI_API = {
310
343
  this.getProperties(),
311
344
  this.getContextVariables(),
312
345
  this.getTemplateVariables(),
346
+ this.getPnp(),
313
347
  this.getStateFromState(),
314
348
  this.getBoundTo(),
315
349
  this.getStatus()
316
- );
350
+ )
317
351
  },
318
352
 
319
353
  injectClassAttribute () {
320
354
  if (this.getPci().classAttribute.length == 0) return
321
- let wrapperEl = document.getElementById('qti3-player-pci-wrapper');
322
- wrapperEl.classList.add(this.getPci().classAttribute);
355
+ let wrapperEl = document.getElementById('qti3-player-pci-wrapper')
356
+ wrapperEl.classList.add(this.getPci().classAttribute)
323
357
  },
324
358
 
325
359
  injectMarkup () {
@@ -327,7 +361,7 @@ const QTI_PCI_API = {
327
361
  `<div
328
362
  id="qti3-player-pci-markup"
329
363
  class="qti-interaction-markup"
330
- >${this.getPci().markup}</div>`;
364
+ >${this.getPci().markup}</div>`
331
365
  },
332
366
 
333
367
  injectStylesheets () {
@@ -390,7 +424,7 @@ const QTI_PCI_API = {
390
424
  * @param {Object} contextVariables
391
425
  * @param {Object} templateVariables
392
426
  * @param {String} state A prior state
393
- * @param {Object} boundTo The response variable this PCI is bound to and its value
427
+ * @param {Object} boundTo The response variable's value
394
428
  * @param {String} status Item lifecycle status; e.g., 'interacting'
395
429
  */
396
430
  launchPci (
@@ -400,14 +434,15 @@ const QTI_PCI_API = {
400
434
  properties,
401
435
  contextVariables,
402
436
  templateVariables,
437
+ pnp,
403
438
  state,
404
439
  boundTo,
405
440
  status) {
406
441
 
407
- console.log('[PCI Context] Interaction Dependencies: ', this.getModuleDependencies());
442
+ console.log('[PCI Context] Interaction Dependencies: ', this.getModuleDependencies())
408
443
 
409
444
  // Load module resolution
410
- require.config(this.getModuleResolution());
445
+ require.config(this.getModuleResolution())
411
446
 
412
447
  // Launch it!
413
448
  require(this.getModuleDependencies(), function(ctx) {
@@ -416,71 +451,77 @@ const QTI_PCI_API = {
416
451
  properties: properties,
417
452
  templateVariables: templateVariables,
418
453
  contextVariables: contextVariables,
454
+ pnp: pnp,
419
455
  boundTo: boundTo,
420
456
  responseIdentifier: responseIdentifier,
421
457
  onready: ctx.notifyReady,
422
458
  ondone: ctx.notifyDone,
423
459
  status: status
424
- };
460
+ }
425
461
 
426
- console.log('[PCI Context] Configuration: ', configuration);
462
+ console.log('[PCI Context] Configuration: ', configuration)
427
463
  console.log('[PCI Context] State: ', (state === null ? undefined : state))
428
464
 
429
465
  if (state === null)
430
466
  ctx.getInstance(typeIdentifier, dom, configuration)
431
467
  else
432
- ctx.getInstance(typeIdentifier, dom, configuration, state);
468
+ ctx.getInstance(typeIdentifier, dom, configuration, state)
433
469
 
434
- });
470
+ })
471
+ },
472
+
473
+ setRenderingProperties (properties) {
474
+ qtiCustomInteractionContext.setRenderingProperties(this.getInstance(), properties)
435
475
  },
436
476
 
437
477
  NotifyPciChildLoaded () {
438
- if (self == top) return;
478
+ if (self == top) return
439
479
 
440
480
  // Extract the identifier qs param
441
- const responseIdentifier = this.getQueryParameterByName('identifier');
442
- this.setResponseIdentifier(responseIdentifier);
481
+ const responseIdentifier = this.getQueryParameterByName('identifier')
482
+ this.setResponseIdentifier(responseIdentifier)
443
483
 
444
- window.parent.postMessage({ message: 'PciChildLoaded', identifier: this.getResponseIdentifier(), success: true },'*');
484
+ window.parent.postMessage({ message: 'PciChildLoaded', identifier: this.getResponseIdentifier(), success: true },'*')
445
485
  },
446
486
 
447
487
  NotifyPciReady (instance, state) {
448
- this.setInstance(instance);
488
+ this.setInstance(instance)
449
489
 
450
- if (self == top) return;
490
+ if (self == top) return
451
491
 
452
- const height = this.getDom().clientHeight;;
453
- const computedHeight = (height) ? height : 0;
454
- const width = this.getDom().clientWidth;
455
- const computedWidth = (width) ? width : 0;
492
+ const height = this.getDom().clientHeight
493
+ const computedHeight = (height) ? height : 0
494
+ const width = this.getDom().clientWidth
495
+ const computedWidth = (width) ? width : 0
456
496
 
457
- window.parent.postMessage({ message: 'PciReady', identifier: this.getResponseIdentifier(), width: computedWidth, height: computedHeight, success: true },'*');
497
+ window.parent.postMessage({ message: 'PciReady', identifier: this.getResponseIdentifier(), width: computedWidth, height: computedHeight, success: true },'*')
458
498
  },
459
499
 
460
500
  NotifyPciDone (instance, response, state, status) {
461
- if (self == top) return;
501
+ if (self == top) return
462
502
 
463
503
  const stringifiedState = JSON.stringify({
464
504
  response: (typeof response === 'undefined' ? null : response),
465
505
  state: (typeof state === 'undefined' ? null : state)
466
- });
506
+ })
467
507
 
468
- window.parent.postMessage({ message: 'PciDone', identifier: this.getResponseIdentifier(), state: stringifiedStateObject, status: status, success: true },'*');
508
+ window.parent.postMessage({ message: 'PciDone', identifier: this.getResponseIdentifier(), state: stringifiedStateObject, status: status, success: true },'*')
469
509
  },
470
510
 
471
511
  NotifyPciStateReady (stringifiedStateObject) {
472
- if (self == top) return;
473
- window.parent.postMessage({ message: 'PciGetState_Reply', identifier: this.getResponseIdentifier(), state: stringifiedStateObject, success: true },'*');
512
+ if (self == top) return
513
+ window.parent.postMessage({ message: 'PciGetState_Reply', identifier: this.getResponseIdentifier(), state: stringifiedStateObject, success: true },'*')
474
514
  },
475
515
 
476
516
  NotifyPciInteractionChanged (valid, value) {
477
- if (self == top) return;
517
+ if (self == top) return
478
518
 
479
- const stringifiedState = JSON.stringify({
519
+ const stringifiedStateObject = JSON.stringify({
480
520
  valid: (typeof valid === 'undefined' ? null : valid),
481
521
  value: (typeof value === 'undefined' ? null : value)
482
- });
483
- window.parent.postMessage({ message: 'PciInteractionChanged', identifier: this.getResponseIdentifier(), state: stringifiedStateObject, success: true },'*');
522
+ })
523
+
524
+ window.parent.postMessage({ message: 'PciInteractionChanged', identifier: this.getResponseIdentifier(), state: stringifiedStateObject, success: true },'*')
484
525
  },
485
526
 
486
527
  /**
@@ -491,20 +532,20 @@ const QTI_PCI_API = {
491
532
  * @param {String} name The name of the paramter to get from the URL.
492
533
  */
493
534
  getQueryParameterByName (name) {
494
- let regex = new RegExp("[\\?&]" + name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]') + '=([^&#]*)');
495
- let results = regex.exec(window.location.search);
535
+ let regex = new RegExp("[\\?&]" + name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]') + '=([^&#]*)')
536
+ let results = regex.exec(window.location.search)
496
537
 
497
- if (results === null) return '';
538
+ if (results === null) return ''
498
539
 
499
- return decodeURIComponent(results[1].replace(/\+/g, " "));
540
+ return decodeURIComponent(results[1].replace(/\+/g, " "))
500
541
  },
501
542
 
502
543
  bindWindowEventListener (element, eventName, eventHandler) {
503
544
  if (element.addEventListener) {
504
- element.addEventListener(eventName, eventHandler, false);
545
+ element.addEventListener(eventName, eventHandler, false)
505
546
  } else if (element.attachEvent) {
506
547
  // For IE8 and older IE
507
- element.attachEvent('on' + eventName, eventHandler);
548
+ element.attachEvent('on' + eventName, eventHandler)
508
549
  }
509
550
  },
510
551
 
@@ -512,73 +553,101 @@ const QTI_PCI_API = {
512
553
  // create a mutation observer instance
513
554
  let observer = new MutationObserver(function(mutations) {
514
555
  mutations.forEach(function(mutation) {
515
- let bounds = element.getBoundingClientRect();
516
- let width = Math.ceil(bounds.right);
517
- let height = Math.ceil(bounds.bottom);
556
+ let bounds = element.getBoundingClientRect()
557
+ let width = Math.ceil(bounds.right)
558
+ let height = Math.ceil(bounds.bottom)
518
559
  if (Math.abs(width - this.width) > 15 || Math.abs(height - this.height) > 15) {
519
- this.width = width;
520
- this.height = height;
560
+ this.width = width
561
+ this.height = height
521
562
  const msg = {
522
563
  width: width,
523
564
  height: height
524
- };
525
- window.parent.postMessage({ message: 'PciResize', identifier: this.getResponseIdentifier(), height: msg.height, width: msg.width, success: true },'*');
565
+ }
566
+ window.parent.postMessage({ message: 'PciResize', identifier: this.getResponseIdentifier(), height: msg.height, width: msg.width, success: true },'*')
526
567
  }
527
- }.bind(this));
528
- }.bind(this));
568
+ }.bind(this))
569
+ }.bind(this))
529
570
 
530
571
  observer.observe(element, {
531
572
  attributes: true,
532
573
  childList: true,
533
574
  characterData: true,
534
575
  subtree: true
535
- });
576
+ })
536
577
  },
537
578
 
538
579
  trackQtiInteractionChanged (domElement) {
539
- this.onQtiInteractionChanged = this.onQtiInteractionChangedHandler.bind(this);
540
- domElement.addEventListener('qti-interaction-changed', this.onQtiInteractionChanged);
580
+ this.onQtiInteractionChanged = this.onQtiInteractionChangedHandler.bind(this)
581
+ domElement.addEventListener('qti-interaction-changed', this.onQtiInteractionChanged)
541
582
  },
542
583
 
543
584
  onQtiInteractionChangedHandler (event) {
544
- event.preventDefault();
585
+ event.preventDefault()
545
586
 
546
587
  if (typeof event.detail === 'undefined') {
547
- console.log('[QtiInteractionChanged][Engine][Module Error]: event is missing required "detail" property', event);
548
- return;
588
+ console.log('[QtiInteractionChanged][Engine][Module Error]: event is missing required "detail" property', event)
589
+ return
549
590
  }
550
591
 
551
- console.log('[QtiInteractionChanged][Engine]', event.detail);
552
- this.NotifyPciInteractionChanged(event.detail.valid, event.detail.value);
592
+ // event.detail has four required properties:
593
+ // {
594
+ // interaction: <instance>,
595
+ // responseIdentifier: <interaction response identifer>,
596
+ // valid: <validity boolean>,
597
+ // value: <response value>
598
+ // }
599
+ if (typeof event.detail.interaction === 'undefined') {
600
+ console.log('[QtiInteractionChanged][Engine][Module Error]: event detail is missing required "interaction" property', event.detail)
601
+ return
602
+ }
603
+ if (typeof event.detail.responseIdentifier === 'undefined') {
604
+ console.log('[QtiInteractionChanged][Engine][Module Error]: event detail is missing required "responseIdentifier" property', event.detail)
605
+ return
606
+ }
607
+ if (typeof event.detail.valid === 'undefined') {
608
+ console.log('[QtiInteractionChanged][Engine][Module Error]: event detail is missing required "valid" property', event.detail)
609
+ return
610
+ }
611
+ if (typeof event.detail.value === 'undefined') {
612
+ console.log('[QtiInteractionChanged][Engine][Module Error]: event detail is missing required "value" property', event.detail)
613
+ return
614
+ }
615
+
616
+ console.log('[QtiInteractionChanged][Engine]', event.detail)
617
+ this.NotifyPciInteractionChanged(event.detail.valid, event.detail.value)
553
618
  }
554
- };
619
+ }
555
620
 
556
621
  window.onload = (event) => {
557
622
 
558
623
  QTI_PCI_API.bindWindowEventListener(window, 'message', function(e) {
559
624
  switch (e.data.message) {
560
625
  case 'PciLoadInteraction':
561
- QTI_PCI_API.setState(e.data.state);
562
- QTI_PCI_API.initialize(JSON.parse(e.data.pci));
563
- break;
626
+ QTI_PCI_API.setState(e.data.state)
627
+ QTI_PCI_API.initialize(JSON.parse(e.data.pci))
628
+ break
564
629
 
565
630
  case 'PciGetState_Request':
566
631
  QTI_PCI_API.getInteractionState()
567
- break;
632
+ break
568
633
 
569
634
  case 'PciResizeContainerWidth':
570
- break;
635
+ break
636
+
637
+ case 'PciSetRenderingProperties':
638
+ QTI_PCI_API.setRenderingProperties(e.data.properties)
639
+ break
571
640
 
572
641
  default:
573
642
  }
574
- });
643
+ })
575
644
 
576
645
  // Notify the parent window that this Page is loaded.
577
646
  // Upon receipt of this message, the parent window should
578
647
  // send a PciLoadInteraction message to this page, which
579
648
  // will launch the PCI with a configuration and state.
580
- QTI_PCI_API.NotifyPciChildLoaded();
581
- };
649
+ QTI_PCI_API.NotifyPciChildLoaded()
650
+ }
582
651
  </script>
583
652
  <body>
584
653
  <div id="qti3-player-pci-wrapper" class="">